什么构成C中的常量表达式的详细信息?

R..*_*R.. 9 c standards constants constant-expression

C定义了至少3个级别的"常量表达式":

  • 常量表达(不合格)
  • 算术常数表达式
  • 整数常量表达式

6.6第3段内容如下:

常量表达式不应包含赋值,递增,递减,函数调用或逗号运算符,除非它们包含在未评估的子表达式中.

那么这意味着1,2不是一个恒定的表达式吗?

第8段内容如下:

算术常量表达式应具有算术类型,并且只能具有整数常量,浮点常量,枚举常量,字符常量和sizeof表达式的操作数.算术常量表达式中的转换运算符只能将算术类型转换为算术类型,除非作为sizeof运算符的操作数的一部分,其结果为整数常量.

什么是操作数(union { uint32_t i; float f; }){ 1 }.f?如果1是操作数,那么这可能是一个算术常量表达式,但如果{ 1 }是操作数,则显然不是.

编辑:另一个有趣的观察:7.17第3段要求结果是offsetof类型的整数常量表达式size_t,但offsetof据我所知,标准实现不需要是标准的整数常量表达式.这当然是可以的,因为允许实现(在6.6第10段下)接受其他形式的常量表达式,或者实现offsetof__builtin_offsetof而不是通过指针减法.但是,这种观察的本质是,如果你想offsetof在需要整数常量表达式的上下文中使用,你真的需要使用实现提供的宏而不是自己的.

Chr*_*utz 2

根据您的阅读,1,2这不是一个恒定的表达式。我不知道为什么不是,只是我同意你的观点,它不是(尽管事实上它可能应该是)。

6.5.2 指定复合文字作为后缀运算符。所以在

(union { uint32_t i; float f; }){ 1 }.f
Run Code Online (Sandbox Code Playgroud)

操作数是(union { uint32_t i; float f; }){ 1 }andf运算符.。它不是算术常量表达式,因为第一个参数是类型union,但它是常量表达式。

更新:我这是基于对标准的不同解释。

我之前的推理是(union { uint32_t i; float f; }){ 1 }.f满足常量表达式的标准,因此是常量表达式。我仍然认为它符合常量表达式的标准(6.6 第 3 段),但它不是常量表达式的任何标准类型(整数、算术或地址),因此仅受 6.6 段约束为常量表达式10,它允许实现定义的常量表达式。

我也一直想得到你的编辑。我本来认为 的“hack”实现offsetof是一个常量表达式,但我认为它与上面相同:它满足常量表达式(可能还有地址常量)的标准,但不是整数常量表达式,并且因此,在 6.6 第 10 段之外无效。