假设我有一个场景,我需要确保我的代码中使用的值是编译时常量(例如,可能是对P10 规则 2 “固定循环边界”的严格解释)。如何在 C 语言级别强制执行此操作?
C在语言级别支持整数常量表达式的概念。必须有可能找到一种方法来利用这一点,以便只有符合本规范的值才能在表达式中使用,对吧?例如:
for (int i = 0; i < assert_constant(10); ++i) {...
一些部分解决方案不够通用,无法在多种情况下使用:
位域:
static_assert
在 C11 之前的 C中实现的经典策略是使用一个位域,当条件失败时其值将是非法的:struct { int _:(expression); }
虽然这可以很容易地包装以用作表达式的一部分,但它根本不通用 -
expression
"[may] 的最大值不超过将指定类型的对象的宽度,如果省略了冒号和表达式"(C11 6.7.2.1),它对expression
(通常可能是 64)的大小设置了非常低的便携限制。它也可能不是负面的。枚举:要求
enum
任何初始化表达式都是整数常量表达式。但是,enum
声明不能嵌入到表达式中(与struct
定义不同),需要它自己的语句。由于枚举器列表中的标识符被添加到周围的作用域中,因此我们每次也需要一个新名称。__COUNTER__
没有标准化,所以没有办法从宏中实现这一点。案例:同样,一行的参数表达式
case
必须是一个整数常量。但这需要周围的switch
陈述。这并不比 好很多enum
,而且它是您不想隐藏在宏中的那种东西(因为它会生成真实的语句,即使它们很容易被优化器删除)。数组声明:从 C99 开始,数组大小甚至不必是常量,这意味着它无论如何都不会产生所需的错误。这也是一个需要将名称引入周围范围的语句,遇到与
enum
.
肯定有某种方法可以在可重复的宏中隐藏常量检查,传递值(因此它可以用作表达式),并且不需要语句行或引入额外的标识符?