这个问题很久以前在comp.lang.c++.moderated 的主题init-declarator-list analysis order 下提出,结论是Yes。
虽然我看到了 full-expression 参数,但我没有看到评估参数的顺序。所以我认为这是未指定的。
问题的相关部分是:
在此声明和定义中:
int a = 2, b = a;
是否保证 b 将始终初始化为 2 ?如果是,那么
我们可以说在 b = a 之前总是分析(或评估)a = 2 吗?
答案的相关部分是:
是的。严格来说,程序的可观察行为必须是
好像声明的“a = 2”部分的所有副作用
发生在“b = a”部分的评估开始之前。 (在
练习,当然,在这个简单的例子中,编译器可以分配 2
a 和 b 以任何顺序,甚至并行,因为这样做
会导致相同的可观察行为。)
再往下:
然而,在这种特殊情况下,它确实分隔了声明符
列出单独的声明器;每个声明符都包含一个完整的
表达式,并且声明符按顺序计算。
更新
使每个 init-declator 成为 完整表达式 的原因很微妙,但据我所知,遵循我在 Are multiple mutations of the same variable within initializer lists undefined behavior pre C++11 中使用的相同逻辑。在这种情况下,我们从第 8 节中定义的语法开始:
init-declarator-list:
init-declarator
init-declarator-list , init-declarator
init-declarator:
declarator initializeropt
下一个重点是在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
在这两种情况下,我们都有 = initializer-clause 将我们带到 assignment-expression,如果我们遵循第 5 节中的语法,则会带来我们回到 primary-expression,它可以给我们一个 literal 或 id-expression。
所以我们确实有用语法逗号分隔的完整表达式,所以我们有:
int x = 42, y = x;
^ ^
| end full-expression
end full-expression
根据1.9 段14,我们看到:
与
全表达式在每个值计算和边之前排序
与要评估的下一个完整表达式相关联的效果。8.
至于评估的顺序,我认为这没有指定,适用于 defect report 430 的初始化列表的相同逻辑似乎也适用于这里。在 C++11 中,初始化器列表的语言在8.5.4 部分中添加了以下内容:
在花括号初始化列表的初始化列表中,
初始化子句,包括任何由包扩展产生的子句
(14.5.3),按照它们出现的顺序进行评估。 [...]
initializer 没有这样的等价物。