问题描述
C定义了至少3个级别的恒定表达:
C defines at least 3 levels of "constant expression":
- 恒定表达(不合格)
- 算术常量表达式
- 整数常量表达式
6.6第3段内容为:
6.6 paragraph 3 reads:
所以这意味着 1,2
不是常数表达式吗?
So does this mean 1,2
is not a constant expression?
第8段显示:
中的操作数是什么(联合{uint32_t i; float f;}){1} .f
?如果 1
是操作数,则可能是算术常数表达式,但是如果 {1}
是操作数,
What are the operands in (union { uint32_t i; float f; }){ 1 }.f
? If 1
is the operand, then this is presumably an arithmetic constant expression, but if { 1 }
is the operand, then it's clearly not.
编辑:另一个有趣的观察结果:7.17第3款要求 c $ c>是类型 size_t
的整数常量表达式,但到目前为止, offsetof
的标准实现我可以说,按标准不需要是整数常量表达式。这当然是可以的,因为允许实现(根据6.6第10节)接受其他形式的常量表达式,或将 offsetof
宏实现为 __ builtin_offsetof
而不是通过指针减法。但是,这种观察的本质是,如果要在需要整数常量表达式的上下文中使用 offsetof
,则确实需要使用由
Another interesting observation: 7.17 paragraph 3 requires the result of offsetof
to be an integer constant expression of type size_t
, but the standard implementations of offsetof
, as far as I can tell, are not required to be integer constant expressions by the standard. This is of course okay since an implementation is allowed (under 6.6 paragraph 10) to accept other forms of constant expressions, or implement the offsetof
macro as __builtin_offsetof
rather than via pointer subtraction. The essence of this observation, though, is that if you want to use offsetof
in a context where an integer constant expression is required, you really need to use the macro provided by the implementation and not roll your own.
推荐答案
根据您的阅读, 1,2
不是常量表达式。我不知道为什么不是这样,只是我同意你所说的不是(尽管事实可能应该如此)。
Based on your reading, 1,2
isn't a constant expression. I don't know why it isn't, just that I agree with you that it isn't (despite the fact that it probably should be).
6.5。 2指定复合文字作为后缀运算符。因此,在
6.5.2 specifies compound literals as a postfix operator. So in
(union { uint32_t i; float f; }){ 1 }.f
操作数为(union {uint32_t i; float f;}){1}
和 f
到。
运算符。它不是算术常数表达式,因为第一个参数是 union
类型,但它是常数表达式。
The operands are (union { uint32_t i; float f; }){ 1 }
and f
to the .
operator. It is not an arithmetic constant expression, since the first argument is a union
type, but it is a constant expression.
更新:我是基于对标准的另一种解释。
UPDATE: I was basing this on a different interpretation of the standard.
我以前的理由是( union {uint32_t i; float f;}){1} .f
满足常量表达式的标准,因此是常量表达式。我仍然认为它符合常量表达式的标准(第6.6段第3款),但它不是常量表达式的任何标准类型(整数,算术或地址),因此只能由6.6段作为常量表达式10,它允许实现定义的常量表达式。
My previous reasoning was that (union { uint32_t i; float f; }){ 1 }.f
met the criteria for a constant expression, and was therefore a constant expression. I still think it meets the criteria for a constant expression (6.6 paragraph 3) but that it is not any of the standard types of constant expressions (integer, arithmetic, or address) and is therefore only subject to being a constant expression by 6.6 paragraph 10, which allows implementation-defined constant expressions.
我也一直想进行编辑。我要争论的是 offsetof
的 hack实现是一个常量表达式,但我认为它与上面的相同:它满足常量表达式的标准(并且可能是一个地址常量),但它不是整数常量表达式,因此在6.6第10段之外无效。
I'd also been meaning to get to your edit. I was going to argue that the "hack" implementation of offsetof
was a constant expression, but I think it's the same as above: it meets the criteria for a constant expression (and possibly an address constant) but is not an integer constant expression, and is therefore invalid outside of 6.6 paragraph 10.
这篇关于C中构成常量表达式的细节是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!