C在编译时检查数组内容

时间:2019-02-11 08:51:44

标签: c arrays compile-time

我有一个枚举和一个结构数组。结构中的第一个字段是枚举类型。现在,我想在编译时检查第一个数组元素的第一个字段中的值是否与枚举类型的第一个值相同。与第二个元素相同,依此类推...

基本上是这样的:

typedef enum {
   A = 0,
   B,
   C
} enumerator1;

typedef struct {
   enumerator1   a;
   unsigned char foo;
   unsigned char bar;
} structure1;

const structure1 array1[3] =
{
   {A, 1, 1},   //This element should contain A
   {C, 1, 1},   //This element should contain B
   {B, 1, 1}    //This element should contain C
};

在上面的示例中,B和C被交换了,我想在编译时捕获它。 我正在寻找的是这样的:

#if array1[0].a != A
#error
#endif

但是这不起作用,编译器说“令牌“ [”在预处理程序表达式中无效”。 我也尝试过类似这样的方法:

typedef unsigned char Check[(array1[0].a != A) ? 1 : -1];

但结果相同。 如果可能的话,如何进行这种检查?

谢谢。

1 个答案:

答案 0 :(得分:2)

不能。从概念上讲,C中的数组是运行时的东西。没有任何便携式方法可以对此强制执行comptime断言。

这并不意味着优化的编译器不会对其进行检查。

如果我进行import 'bootstrap';并查看反汇编,我可以看到在启用优化的情况下进行编译时,gcc和clang都完全将这段代码删除了。

有一个GCC技巧可以使您将优化器知识转化为comptime断言(或ASAP断言) 我称之为)。

if(!(array1[0].a == A)) abort();

缺点是它是GCC专用的,运行时开销很小(易失性写操作,可以通过将ndebug设置为1来关闭它,但是这样就不会出现编译时失败),而且误报。