我想使用 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
当然这不起作用,因为在这种情况下
START
和 END
只是 __LINE__
宏的重新定义。#
和 ##
运算符,但在预处理器运行时我无法让预处理器评估 START
和 END
。
我的问题是:这可能吗?
在运行时检查数组的大小不是一个选项。
感谢您提前提供任何提示或想法!
您不应该将这些宏用于此目的:如果您在某处引入额外的行,代码将变得完全无法维护。如果行数太少怎么办?
使用静态断言代替宏:
static_assert(sizeof(string_list) / sizeof(*string_list) == SOME_CONSTANT,
"Wrong number of entries in string list.");
如果你没有使用支持 static_assert 的 C11,你可以自己编写这样的断言,例如这样:
#define COMPILE_TIME_ASSERT(expr) {typedef uint8_t COMP_TIME_ASSERT[(expr) ? 1 : 0];}
[确认 @Lundin 指出您可以使用
typedef
]
这是一种方法
typedef uint8_t START[__LINE__]; /*put this on one line*/
typedef uint8_t END[__LINE__]; /*put this on another line*/
sizeof(END) - sizeof(START)
是一个 编译时 表达式,给出行偏移量。
放入宏并根据口味重命名
START
和 END
。
如果您这样声明数组:
static const char* string_list[42] = {...
编译器会告诉您是否提供了过多的初始化程序。如果需要,您可以提供哨兵条目来标记结束:
static char* string_list[43] = { ..., NULL } ;
如果您需要知道的话,也许可以编写一个函数来确定运行时的长度。