Vin*_*ent 11 c++ initialization undefined-behavior language-lawyer c++11
以下是完美定义的:
int x = 42, y = x;
Run Code Online (Sandbox Code Playgroud)
即严格等同于:
int x = 42;
int y = x;
Run Code Online (Sandbox Code Playgroud)
编辑:问题不是关于风格(我知道这是错误的......),问题是"理论上的"
正确的答案是
int x = 42, y = x;
Run Code Online (Sandbox Code Playgroud)
和
int x = 42;
int y = x;
Run Code Online (Sandbox Code Playgroud)
通常是等价的(不严格).
考虑标准的§8声明符[dcl.decl]:
3声明中的每个init-declarator都会被单独分析,就好像它本身就在声明中一样.
并在脚注[100]中进一步解释:
具有多个声明符的声明通常等效于具有单个声明符的相应声明序列.那是
T D1,D2,... Dn;
通常相当于
T D1; T D2; ...... T Dn;
其中T是decl-speci-er-seq,每个Di都是init-declarator.
上述保证x = 42和y = x将被单独评估.但是,正如@Praetorian在评论中正确指出的那样,脚注不是规范性的.
这意味着评估的顺序没有很好地定义,并且实现者也可以以相反的顺序(即,T Dn; ...T D2; T D1;)来实现对声明的评估.
有人可能会说,逗号运算符是保证从左到右的评估.但是,事实并非如此.根据K&R [K&R II,3.6 p.63],这也适用于C++:
将函数参数,声明中的变量等分开的逗号不是逗号运算符,也不保证从左到右的求值.
这个问题是在很早以前由comp.lang.c ++。mode主持的,主题为init-declarator-list分析顺序,结论是Yes。
虽然我看到了full-expression参数,但是看不到评估参数的顺序。因此,我认为这是未指定的。
问题的相关部分是:
在此声明和定义中:
int a = 2,b = a;
是否保证b将始终初始化为2?如果是,那么我们可以说a = 2总是在b = a之前被分析(或评估吗?)。
答案的相关部分是:
是。严格说来,程序的可观察行为必须好像声明的“ a = 2”部分的所有副作用都发生在对“ b = a”部分的评估开始之前。(当然,在实践中,在这个简单的示例中,编译器可以以任意顺序或什至并行地将2分配给a和b,因为这样做会导致相同的可观察到的行为。)
再往下走:
但是,在这种特殊情况下,它会将声明符列表分隔为单独的声明符;每个声明符都包含一个完整的表达式,并且声明符按顺序求值。
更新资料
使每个init-declator成为完整表达式的原因很微妙,但据我所知,遵循的逻辑与我在初始化器中对同一变量的多次突变列出C ++ 11之前的未定义行为有关。在这种情况下,我们从第8节中定义的语法开始:
init-declarator-list:
init-declarator
init-declarator-list , init-declarator
init-declarator:
declarator initializeropt
Run Code Online (Sandbox Code Playgroud)
下一个重点是初始化语法,该语法在以下部分中介绍8.5:
initializer:
brace-or-equal-initializer
( expression-list )
brace-or-equal-initializer:
= initializer-clause
braced-init-list
initializer-clause:
assignment-expression
braced-init-list
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,我们都有=初始化子句,这使我们进入了赋值表达式,如果我们按照第5节中的语法进行操作,则会使我们回到primary-expression,它可以为我们提供文字或id-expression。
因此,我们确实有用语法逗号分隔的完整表达式,因此我们具有:
int x = 42, y = x;
^ ^
| end full-expression
end full-expression
Run Code Online (Sandbox Code Playgroud)
根据1.9第14段,我们看到:
在与要评估的下一个完整表达式关联的每个值计算和副作用之前,对与一个完整表达式关联的每个值计算和副作用进行排序。8。
至于评估顺序,我认为这没有指定,适用于初始化程序列表的缺陷报告430的逻辑似乎也适用于此处。在C ++ 11中,初始化器列表的语言已在部分中进行了以下补充8.5.4:
在带有括号的初始列表的初始列表中,初始子句(包括由包扩展(14.5.3)导致的子句)按照它们出现的顺序进行评估。[...]
初始化器没有这样的等效项。
| 归档时间: |
|
| 查看次数: |
598 次 |
| 最近记录: |