计算C预处理器中两个代码位置之间的行数

Chr*_*ris 5 c c-preprocessor

我想使用C预处理器来计算两个代码位置之间的行数.基本想法是这样的:

#define START __LINE__
static char* string_list[] = {
    "some string",
    "another string",
    ...
    "last string"
};
#define END __LINE__
#if END - START > 42
    #error Too many entries
#endif
Run Code Online (Sandbox Code Playgroud)

当然这不起作用,因为在这种情况下START,END仅仅是对__LINE__宏的重新定义.
我正在玩###运算符,但我无法让预处理器进行评估START,END而预处理器正在运行.

我的问题是:这有可能吗?

不能选择在运行时检查数组的大小.
预先感谢任何提示或想法!

Lun*_*din 8

您不应该为此目的使用这些宏:如果您在某处引入额外的行,代码将变得完全无法维护.如果行太少会怎么样?

而不是宏,使用静态断言:

static_assert(sizeof(string_list) / sizeof(*string_list) == SOME_CONSTANT,
               "Wrong number of entries in string list.");
Run Code Online (Sandbox Code Playgroud)

如果您没有使用支持static_assert的C11,您可以自己编写这样的断言,例如:

#define COMPILE_TIME_ASSERT(expr) {typedef uint8_t COMP_TIME_ASSERT[(expr) ? 1 : 0];}
Run Code Online (Sandbox Code Playgroud)

  • 我建议让数组的大小为-1而不是0,以使断言失败.刚刚使用-std = c99进行GCC 4.9.0测试,没有指定其他特殊开关,代码编译与上面的宏一样好.如果设置了-pedantic,则数组大小仅为0.数组大小-1确实在有或没有开关时断开,因此它使其更可靠. (2认同)

Bat*_*eba 5

[确认@Lundin谁指出你可以使用typedef]

这是一种方式

typedef uint8_t START[__LINE__]; /*put this on one line*/

typedef uint8_t END[__LINE__]; /*put this on another line*/
Run Code Online (Sandbox Code Playgroud)

sizeof(END) - sizeof(START)是一个编译时表达式,给出行偏移量.

放入宏并重命名STARTEND品尝.