如何在C语言中结合数组字面量使用_Static_assert?
问题原因
在C标准中,你使用的(int[]){2, 1, 0}属于自动存储期的复合字面量,这类对象的下标访问不属于编译期常量表达式,因此无法在_Static_assert中使用——_Static_assert要求断言条件必须是编译期可求值的常量表达式。
解决方法
方法1:改用静态存储期的复合字面量
给复合字面量加上static关键字,将其变为静态存储期对象。根据C11及后续标准,静态存储期对象的元素访问(当下标为常量表达式时)属于合法的常量表达式,编译器可以在编译期求值:
_Static_assert((static int[]){2, 1, 0}[2], "err");
这个方法改动最小,GCC、Clang、MSVC等主流编译器均支持。
方法2:用枚举类型存储常量值
将数组中的字面量定义为枚举成员,枚举成员本身属于常量表达式,可直接用于_Static_assert:
// 直接在断言中定义匿名枚举 _Static_assert(((enum { V0 = 2, V1 = 1, V2 = 0 })V2), "err"); // 或者先定义枚举再使用,可读性更好 enum { VAL_2 = 0, VAL_1 = 1, VAL_0 = 2 }; _Static_assert(VAL_2, "err");
方法3:借助预处理器宏提取元素
通过预处理器宏展开来直接获取数组字面量中的指定元素,完全在预处理阶段完成求值:
#define ARRAY_LITERAL 2, 1, 0 #define GET_NTH_ELEM(arr, n) _GET_NTH_ELEM(arr, n) // 针对长度为3的数组,定义对应参数的宏 #define _GET_NTH_ELEM(e0, e1, e2, n) e##n _Static_assert(GET_NTH_ELEM(ARRAY_LITERAL, 2), "err");
注意:这个方法仅适用于固定长度的数组,需要根据数组长度调整_GET_NTH_ELEM的参数个数。
内容的提问来源于stack exchange,提问作者Abdulmalek Almkainzi
相关产品推荐
相关产品推荐

