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