我想使用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
。
我的问题是:这有可能吗?
不能选择在运行时检查阵列的大小 提前感谢任何提示或想法!
答案 0 :(得分:8)
您不应该为此目的使用这些宏:如果您在某处引入额外的行,代码将变得完全无法维护。如果线路太少会怎么样?
使用静态断言:
而不是宏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];}
答案 1 :(得分:5)
[承认@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
。
答案 2 :(得分:0)
如果你这样声明数组:
static const char* string_list[42] = {...
编译器会告诉您是否提供了太多初始化程序。如有必要,您可以提供标记结尾的哨兵条目:
static char* string_list[43] = { ..., NULL } ;
如果您需要知道,也许可以编写一个函数来确定运行时的长度。