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

时间:2014-07-03 10:51:42

标签: 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

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

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

不能选择在运行时检查阵列的大小 提前感谢任何提示或想法!

3 个答案:

答案 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)是一个编译时表达式,给出了行偏移量。

放入宏并重命名STARTEND

答案 2 :(得分:0)

如果你这样声明数组:

static const char* string_list[42] = {...

编译器会告诉您是否提供了太多初始化程序。如有必要,您可以提供标记结尾的哨兵条目:

static char* string_list[43] = { ..., NULL } ;

如果您需要知道,也许可以编写一个函数来确定运行时的长度。