C 定义了至少 3 个级别的“常量表达式”:
- 常量表达式(不合格)
- 算术常数表达式
- 整数常量表达式
6.6 第 3 段内容如下:
常量表达式不应包含赋值、递增、递减、函数调用或逗号运算符,除非它们包含在未计算的子表达式中。
那么这是否意味着1,2
不是一个常量表达式?
第 8 段内容如下:
算术常量表达式应具有算术类型,并且只能具有整数常量、浮动常量、枚举常量、字符常量和 sizeof 表达式的操作数。算术常量表达式中的强制转换运算符只能将算术类型转换为算术类型,但作为结果为整数常量的 sizeof 运算符的操作数的一部分除外。
中的操作数是(union { uint32_t i; float f; }){ 1 }.f
什么?如果1
是操作数,那么这可能是一个算术常量表达式,但如果{ 1 }
是操作数,那么显然不是。
编辑:另一个有趣的观察:7.17 第 3 段要求结果是offsetof
type 的整数常量表达式size_t
,但offsetof
据我所知,标准的实现不需要是标准的整数常量表达式。这当然没问题,因为允许实现(根据 6.6 第 10 段)接受其他形式的常量表达式,或者实现offsetof
宏__builtin_offsetof
而不是通过指针减法。然而,这个观察的本质是,如果你想offsetof
在需要整数常量表达式的上下文中使用,你真的需要使用实现提供的宏,而不是自己滚动。