比较平等preprocessor宏 [英] Compare preprocessor macros for equality

查看:135
本文介绍了比较平等preprocessor宏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些 .DBC 文件的一些原油生成的头。
由于几个消息从一个阵列重新present要素结构是相等的,因此所产生的宏是相等的。由于我补结构的一些数组中的code,我想省力,并使用相同的宏对所有对象,但要保证这些定义都没有改变,我想在编译时测试如果宏是相等的。

I have some crude generated header from some .dbc files. Since a few of the messages represent elements from an array the structure is equal and so the generated Macros are equal. Since I fill some array of struct in the code I would like to save effort and use the same macro for all objects, but to ensure the definitions have not changed I would like to test at compile time if the macros are equal.

例如:

#define GET_PATTERN_01_PATTERNPOINT02Y(buf) (0 \
    | (uint16)(-(uint16)((buf[7] >> 6) & 0x01) << 15) \
    | (uint8)(+(uint8)((buf[6] >> 0) & 0xff) << 0) \
    | (uint16)(+(uint16)((buf[7] >> 0) & 0x7f) << 8) \
)

#define GET_PATTERN_02_PATTERNPOINT04Y(buf) (0 \
    | (uint16)(-(uint16)((buf[7] >> 6) & 0x01) << 15) \
    | (uint8)(+(uint8)((buf[6] >> 0) & 0xff) << 0) \
    | (uint16)(+(uint16)((buf[7] >> 0) & 0x7f) << 8) \
)

#if GET_PATTERN_01_PATTERNPOINT02Y != GET_PATTERN_02_PATTERNPOINT04Y
#  error blah
#endif

这可能吗?
如果在C ++的一些解决方案,也可能会有帮助。但宏是固定的。

Is this Possible? If there is some solution in C++ that may also help. But the macros are fixed.

推荐答案

这是一个可怕的黑客,但似乎你比如GCC和C11至少工作:

This is a horrible hack, but seems to work for your example for GCC and C11 at least:

#include <assert.h>
#include <string.h>

...

#define STRINGIFY(x) STRINGIFY_(x)
#define STRINGIFY_(x) #x

#define ASSERT_SAME(m1, m2)                                          \
  static_assert(strcmp(STRINGIFY(m1(xxx)), STRINGIFY(m2(xxx))) == 0, \
                #m1"() and "#m2"() differ!")

ASSERT_SAME(GET_PATTERN_01_PATTERNPOINT02Y, GET_PATTERN_02_PATTERNPOINT04Y);

您可能需要通过 -std = C11 -std = gnu11 ,尽管后者不应该在这里需要的。

You might need to pass -std=c11 or -std=gnu11, though the latter shouldn't be needed here.

说明:


  • 字符串化(X)返回 X 作为一个字符串字面量的扩张。我们需要使用做字符串化分两步字符串化_(),因为燮presses宏扩展。 (有一个步骤中,我们会得到&LT; X&gt;中而不是扩大版&LT; X&gt;中

  • STRINGIFY(x) returns the expansion of x as a string literal. We need to do the stringification in two steps using STRINGIFY_() because # suppresses macro expansion. (With one step we'd get "<x>" instead of "expanded version of <x>".)

GCC有一个内置的版本的strcmp() __ builtin_strcmp()),这是用在这里。这恰好是能够常量字符串在编译时进行比较。在code休息,如果你通过 -fno-内置(除非你明确地用 __ builtin_strcmp()

GCC has a built-in version of strcmp() (__builtin_strcmp()) which is used here. It just happens to be able to compare constant strings at compile-time. The code breaks if you pass -fno-builtin (unless you explicitly use __builtin_strcmp()).

static_assert 是C11编译时断言。

static_assert is a C11 compile-time assertion.

随着三种成分上面我们可以将字符串化扩展宏(通过一些虚拟令牌很可能是对的说法是唯一的),并在编译时比较字符串。

With the three ingredients above we can stringify the expanded macros (passing some dummy token that's likely to be unique for the argument) and compare the strings at compile-time.

是的,这是一个黑客...

Yes, this is a hack...

在C ++ 11有更安全的方式来比较在编译时间字符串 - 例如见<一href=\"http://stackoverflow.com/questions/27490858/how-can-you-compare-two-character-strings-statically-at-compile-time\">this回答。

In C++11 there are safer ways to compare strings at compile time -- see e.g. this answer.

作为一个方面说明,你可以在运行时零开销GCC和锵做到这一点。 (以上版本不会为锵工作,因为它是关于挑剔的strcmp(...)== 0 不是一个整型常量前pression 的所要求的 static_assert )。一个运行时检查像

As a side note, you could do this at run-time too with zero overhead for GCC and Clang. (The version above won't work for Clang as it's pickier about strcmp(...) == 0 not being an integer constant expression as required by static_assert.) A run-time check like

if (strcmp(STRINGIFY(m1(xxx)), STRINGIFY(m2(xxx))) != 0) {
    *report error and exit*
}

得到完全优化出来的时候,宏是相等的。甚至不是字符串保存在只读数据段(只需选中)。这是一个更强大的方法,如果你可以不必运行程序,以发现问题现场。

gets completely optimized out when the macros are equal. Not even the strings are kept in the read-only data segment (just checked). It's a more robust approach if you can live with having to run the program to discover the problem.

这篇关于比较平等preprocessor宏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆