C中构成常量表达式的细节是什么? [英] Details of what constitutes a constant expression in C?

查看:297
本文介绍了C中构成常量表达式的细节是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C定义了至少3个级别的恒定表达:

C defines at least 3 levels of "constant expression":


  • 恒定表达(不合格)

  • 算术常量表达式

  • 整数常量表达式

6.6第3段内容为:

6.6 paragraph 3 reads:


常量表达式不得包含赋值,增量,减量,函数调用,
或逗号运算符,除非它们包含在$ p $ b的子表达式。

Constant expressions shall not contain assignment, increment, decrement, function-call, or comma operators, except when they are contained within a subexpression that is not evaluated.

所以这意味着 1,2 不是常数表达式吗?

So does this mean 1,2 is not a constant expression?

第8段显示:


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

An arithmetic constant expression shall have arithmetic type and shall only have operands that are integer constants, floating constants, enumeration constants, character constants, and sizeof expressions. Cast operators in an arithmetic constant expression shall only convert arithmetic types to arithmetic types, except as part of an operand to a sizeof operator whose result is an integer constant.

中的操作数是什么(联合{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中构成常量表达式的细节是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆