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

问题描述 投票:0回答:3

我想使用 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

我的问题是:这可能吗?

在运行时检查数组的大小不是一个选项。
感谢您提前提供任何提示或想法!

c c-preprocessor
3个回答
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];}

7
投票

[确认 @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


0
投票

如果您这样声明数组:

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

编译器会告诉您是否提供了过多的初始化程序。如果需要,您可以提供哨兵条目来标记结束:

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

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

© www.soinside.com 2019 - 2024. All rights reserved.