如何在C中的初始化程序中使用static_assert?

时间:2017-04-27 15:24:54

标签: c gcc macros static-analysis

信不信由你,我想在扩展到指定初始值设定项的宏中使用static_assert

#define INIT(N) \
        /* static_assert((N) < 42, "too large"), */ \
        [(N)] = (N)

int array[99] = { INIT(1), INIT(2), INIT(42) };

我希望来自INIT(42)的错误,但取消注释static_assert是语法错误。 AFAIK static_assert在语法上是一个声明。我如何在这个例子中使用它?

1 个答案:

答案 0 :(得分:7)

#define INIT(N) \
    [(N)] = (sizeof((struct {_Static_assert((N) < 42, "too large");char c[N];}){{0}}.c))

......我不确定自己是如何结束这种憎恶的。但是,嘿,它有效(对于N > 0)!

// A struct declaration is a valid place to put a static_assert
        struct {_Static_assert((N) < 42, "too large");          }
// Then we can place that declaration in a compound literal...
       (struct {_Static_assert((N) < 42, "too large");          }){   }
// But we can't just throw it away with `,`: that would yield a non-constant expression.
// So let's add an array of size N to the struct...
       (struct {_Static_assert((N) < 42, "too large");char c[N];}){{0}}
// And pry N out again through sizeof!
sizeof((struct {_Static_assert((N) < 42, "too large");char c[N];}){{0}}.c)

0 - 友好版本(只需添加然后减去1,以便数组的大小正确):

#define INIT(N) \
    [(N)] = (sizeof((struct { \
        _Static_assert((N) < 42, "too large"); \
        char c[(N) + 1]; \
    }){{0}}.c) - 1)