假设我有一个场景,我需要确保在我的代码中使用的值是编译时常量(例如,可能是对P10 rule 2“固定循环边界”的严格解释)。我如何在C语言级别执行此操作?如何检查表达式在C中是否为常量?
C在语言级支持整数常量表达式的概念。必须有可能找到一种方法来利用这一点,以便只有符合此规范的值才能用于表达式中,对吗?例如:
for (int i = 0; i < assert_constant(10); ++i) {...
一些局部的解决方案,是不是真的足够一般在多种情况是有用的:
位地址:在C之前C11实现
static_assert
一个经典的策略是use a bitfield whose value would be illegal when a condition failed:struct { int _:(expression); }
虽然这可以很容易地缠绕用作表达式的一部分,它根本不是一般的 - 最大值为
expression
“[可以]不超过将被指定的类型的对象的宽度,其中冒号和表达式被省略”(C11 6.7.2.1),其放置非常低关于expression
的幅度的便携式限制(一般可能是64)。它也可能不是负面的。枚举:一个
enum
需求的任何初始化表达式是整数常量表达式。但是,enum
声明不能嵌入到表达式中(不像struct
定义),因此需要声明它自己的声明。由于枚举器列表中的标识符被添加到周围的范围,所以我们每次都需要一个新名称。__COUNTER__
不是标准化的,所以没有办法从宏中实现这一点。case:再次,参数表达式为
case
行必须是整数常量。但是这需要围绕switch
声明。这并不比enum
好很多,这是你不想隐藏在一个宏内部的东西(因为它会生成真实的语句,即使优化器很容易删除)。数组声明:自C99以来,数组大小甚至不一定是常数,这意味着它无论如何不会产生所需的错误。这也是一个声明,需要在周围的范围内引入一个名字,并且遭受与
enum
相同的问题。
肯定有一些方法来隐藏在宏这是重复的,经过(因此它可以作为一个表达式)的值,并且不需要一个语句行或引入额外的标识符持续检查?
另请参阅[此SO帖子](http://stackoverflow.com/questions/9274532/how-to-check-if-a-parameter-is-an-integral-constant-expression-in-ac-preprocess ?rq = 1)? – quantdev
@quantdev *叹*真的以为我已经为这个话题进行了详尽的搜索...... – Leushenko