struct
{
int a,b;
} s = {5, s.a+1};
按照标准,上面例子中读“sa”是否安全,这样s被初始化为a=5,b=6?如果是这样,大多数编译器是否遵守这条规则?
(以上在VC10中编译。)
struct
{
int a,b;
} s = {5, s.a+1};
按照标准,上面例子中读“sa”是否安全,这样s被初始化为a=5,b=6?如果是这样,大多数编译器是否遵守这条规则?
(以上在VC10中编译。)
是的,因为聚合成员初始化是有序的。
[dcl.init.aggr] /2 有:
当聚合由初始化器列表初始化时,如 8.5.4 中所指定,初始化器列表的元素被视为聚合成员的初始化器,按递增的下标或成员顺序。每个成员都是从相应的initializer-clause复制初始化的。
[dcl.init.list] /4 有:
在支撑初始化列表的初始化列表中,初始化子句,包括任何由包扩展 (14.5.3) 产生的子句,按照它们出现的顺序进行评估。也就是说,与给定初始化子句相关联的每个值计算和副作用在初始化器列表的逗号分隔列表中与任何初始化子句相关联的每个值计算和副作用之前进行排序。
聚合成员的复制初始化肯定是副作用([intro.execution] /12),并且必须与相应的初始化子句“关联” ,因为那是它的完整表达式(因为初始化器列表是不是表达式)。
我尝试过的每个最新编译器(MSVC、Clang、g++)都能正确编译它。一些较旧的编译器可能会出错(旧版本的 g++ 以使聚合初始化程序的排序错误而闻名)。