是成员初始化中表达式的求值,它们相对于彼此排序

Are evaluations of expressions in member initialization sequenced with respect to each other?

本文关键字:相对于 排序 初始化 成员 表达式      更新时间:2023-10-16

具体来说,我有:

struct X { X(int i) { cout << i; } };
int f() { cout << 'f'; return 0; }
int g() { cout << 'g'; return 1; }
struct Z {
    Z() : a(f()), b(g()) {}
    X a, b;
};
int main() { Z z; cout << 'n'; }

我知道成员的构造函数保证按照它们在struct中定义的顺序调用,因此0将在1之前打印。但是如何评价他们的论点呢?是否保证是:

f0g1

?或者,也许,

fg01

gf01

也是有效的输出吗?

欢迎参考标准

在c++ 11标准草案中,每个成员初始化式都是一个全表达式,因此所有的副作用必须在下一个副作用被计算之前生效。

12.6.2 初始化基和成员7说:

[…每个mem初始化器执行的初始化构成一个完整表达式。任何mem初始化式中的表达式作为执行初始化的全表达式的一部分进行计算。[…]

1.9 程序执行14段说:

在计算与下一个完整表达式相关的每个值计算和副作用之前,对与完整表达式相关的每个值计算和副作用进行排序。

12.6.2部分的相关语法如下:

ctor-initializer:
   : mem-initializer-list
mem-initializer-list:
   mem-initializer ...opt
   mem-initializer , mem-initializer-list ...opt
[...]

Pre c++ 11对于每个mem-初始化器都没有相同的措辞,是一个完整的表达式,至少在1804年可用的最老的标准草案中没有。但是,据我所知,我在Are中使用的逻辑相同,在初始化器中对同一变量进行多次突变,列出了c++ 11之前的未定义行为,在这种情况下也适用,因此我们应该期望相同的行为 c++ 11以及

根据c++标准

每个mem初始化器执行的初始化构成一个求值。mem初始化式中的任何表达式都计算为执行初始化

的全表达式的一部分

首先会执行完整表达式a(f()),然后执行完整表达式b(g())。

因为结果输出必须是

f0g1