xlr*_*lrg 2 c++ assembly return-value-optimization rvo nrvo
struct X {
void * a;
void * b;
};
X foo( void * u, void * v);
Run Code Online (Sandbox Code Playgroud)
类型X的返回值的地址作为隐藏参数传递给foo()
如果使用-O0编译测试代码,则代码按预期工作
如何强制编译器不为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);
Run Code Online (Sandbox Code Playgroud)
Update2:问题是,编译器优化了x的实例
X x = foo( vp, 0);
x = foo( x.a, 0);
x = foo( x.a, 0)
Run Code Online (Sandbox Code Playgroud)
要么
X x1 = foo( vp, 0);
X x2 = foo( x1.a, 0);
X x3 = foo( x2.a, 0)
Run Code Online (Sandbox Code Playgroud)
无所谓.例如,段错误是因为
X x2 = foo( x1.a, 0);
Run Code Online (Sandbox Code Playgroud)
x1已经过优化,实现尝试访问第一个参数,这是一个空指针.
您也可以在GCC中为单个函数设置优化级别:
X foo(void *u, void *v) __attribute__((optimize("no-elide-constructors");
Run Code Online (Sandbox Code Playgroud)
optimize属性用于指定使用与命令行上指定的不同优化选项编译函数.参数可以是数字或字符串.假设数字是优化级别.假设以O开头的字符串是优化选项,而假定其他选项与-f前缀一起使用.您还可以使用'#pragma GCC optimize'编译指示来设置影响多个函数的优化选项.有关'#pragma GCC optimize'编译指示的详细信息,请参阅功能特定选项Pragma.
例如,这可以用于使用更积极的优化选项编译频繁执行的函数,这些选项可以生成更快更大的代码,而其他函数可以使用不太激进的选项进行编译.
https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html
您也可以尝试#pragma变体:
#pragma GCC push_options
#pragma GCC optimize ("no-elide-constructors")
X foo(void *u, void *v);
#pragma GCC pop_options
Run Code Online (Sandbox Code Playgroud)