struct X {
void * a;
void * b;
};
X foo( void * u, void * v);
- foo() 在汇编器中实现 (i386)
X 类型的返回值的地址作为隐藏参数传递给 foo()
如果使用 -O0 编译测试代码,则代码按预期工作
- 如果使用 -O3 编译发生分段错误(返回值已优化)
- 如果使用 -O3 -fno-elide-constructors 编译,代码将再次按预期工作
如何强制编译器不只为 foo() 添加 RVO(也就是不强制 -fno-elide-constructors)?
Update1:代码必须适用于任意编译器(至少 gcc、clang、msvc),示例代码:
void * vp = bar();
X x = foo( vp, 0);
x = foo( x.a, 0);
x = foo( x.a, 0);
Update2:问题是,编译器优化了 x 的实例
X x = foo( vp, 0);
x = foo( x.a, 0);
x = foo( x.a, 0)
或者
X x1 = foo( vp, 0);
X x2 = foo( x1.a, 0);
X x3 = foo( x2.a, 0)
没关系。例如,发生段错误是因为
X x2 = foo( x1.a, 0);
x1 被优化,实现尝试访问第一个参数,它是一个空指针。