Two*_*nds 24 c++ undefined-behavior language-lawyer ctor-initializer
这会导致未定义的行为吗?具体来说,初始化列表中的递增以及如何评估.
class Wrinkle {
public:
Wrinkle(int i) : a(++i), b(++i), x(++i) {}
private:
int a;
int x;
int b;
};
Run Code Online (Sandbox Code Playgroud)
成员声明和初始化程序列表之间的顺序差异是有意的,因为这是一个可以准确显示该差异的示例,因此请暂时忽略它.
Hol*_*olt 31
这不会生成未定义的行为,因为:
[ 注意:每个mem-initializer执行的初始化构成一个完整表达式.mem-initializer中的任何表达式都将作为执行初始化的full-expression的一部分进行计算.]
5.一个全表达是
- [...]
- init-declarator或mem-initializer,包括初始化程序的组成表达式,
9.在与要评估的下一个全表达式相关联的每个值计算和副作用之前,对与全表达相关联的每个值计算和副作用进行排序.
但要注意:
在非委托构造函数中,初始化按以下顺序进行:
[...]
然后,非静态数据成员按照它们在类定义中声明的顺序进行初始化(同样不管mem-initializers的顺序如何).
所以,你的代码将有效地分配i + 1给a,i + 2给x和i + 3给b.
C++ 17标准包含一个与问题几乎完全相同的示例:
struct B1 { B1(int); /* ... */ };
struct B2 { B2(int); /* ... */ };
struct D : B1, B2 {
D(int);
B1 b;
const int c;
};
D::D(int a) : B2(a+1), B1(a+2), c(a+3), b(a+4) { /* ... */ }
D d(10);
Run Code Online (Sandbox Code Playgroud)
接下来是一个注释:
[注意:每个mem-initializer执行的初始化构成一个完整表达式(4.6).mem-initializer中的任何表达式都将作为执行初始化的full-expression的一部分进行计算. - 结束说明]
...一个mem-initializer,包括初始化器的组成表达式,
短语"包括初始化程序的组成表达"强烈告诉我上述代码是合法的,因为++i在转到下一个初始化程序之前,已经完成了副作用.这只是我对标准的阅读,我很高兴推荐给比我更具有独立经验的人.
(值得注意的是,成员的初始化将按照它们在类中声明的顺序发生,而不是按它们在成员初始化列表中出现的顺序发生).
| 归档时间: |
|
| 查看次数: |
1247 次 |
| 最近记录: |