C 定义了至少 3 个级别的“常量表达式”:
- 常量表达式(非限定)
- 算术常量表达式
- 整型常量表达式
6.6 第 3 段如下:
常量表达式不得包含赋值、递增、递减、函数调用、
或逗号运算符,除非它们包含在不存在的子表达式中
评价。
那么这是否意味着1,2
不是常量表达式吗?
第 8 段内容如下:
算术常量表达式应具有算术类型并且仅具有
操作数为整型常量、浮点常量、枚举常量、字符
常量和 sizeof 表达式。算术常量表达式中的强制转换运算符
只能将算术类型转换为算术类型,除非作为操作数的一部分
sizeof 运算符,其结果是整数常量。
中的操作数是什么(union { uint32_t i; float f; }){ 1 }.f
? If 1
是操作数,那么这可能是一个算术常量表达式,但是如果{ 1 }
是操作数,那么显然不是。
Edit:另一个有趣的观察:7.17 第 3 段要求的结果offsetof
是类型的整型常量表达式size_t
,但是标准实现offsetof
据我所知,标准并不要求必须是整数常量表达式。这当然没问题,因为允许实现(根据 6.6 第 10 段)接受其他形式的常量表达式,或者实现offsetof
宏为__builtin_offsetof
而不是通过指针减法。然而,这个观察的本质是,如果你想使用offsetof
在需要整数常量表达式的上下文中,您确实需要使用实现提供的宏,而不是自己推出宏。
根据您的阅读,1,2
不是一个常量表达式。我不知道为什么不是,只是我同意你的观点,它不是(尽管事实上它可能应该是)。
6.5.2 指定复合文字作为后缀运算符。所以在
(union { uint32_t i; float f; }){ 1 }.f
操作数是(union { uint32_t i; float f; }){ 1 }
and f
to the .
操作员。它不是算术常量表达式,因为第一个参数是union
类型,但它是一个常量表达式。
UPDATE:我的这一点是基于对标准的不同解释。
我之前的推理是(union { uint32_t i; float f; }){ 1 }.f
满足常量表达式的标准,因此是常量表达式。我仍然认为它符合常量表达式的标准(6.6 第 3 段),但它不是常量表达式的任何标准类型(整数、算术或地址),因此仅受 6.6 段约束为常量表达式10,它允许实现定义的常量表达式。
我也一直想得到你的编辑。我要说的是“黑客”实施offsetof
是一个常量表达式,但我认为它与上面相同:它满足常量表达式(可能还有地址常量)的标准,但不是整数常量表达式,因此在 6.6 第 10 段之外无效。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)