问题
struct X {
void * a;
void * b;
};
X foo( void * u, void * v);
- foo() is implemented in assembler (i386)
address of return value of type X is passed as hidden parameter to foo()
if test code is compiled with -O0 the code works as expected
- if compiled with -O3 segmentation fault happens (return value was optimized out)
- if compiled with -O3 -fno-elide-constructors the code works as expected again
how can the compiler be forced no to add RVO for foo() only (aka not forcing -fno-elide-constructors)?
Update1: the code must work for arbitrary compilers (at least gcc ,clang, msvc), example code:
void * vp = bar();
X x = foo( vp, 0);
x = foo( x.a, 0);
x = foo( x.a, 0);
Update2: the problem is, that the compiler optimizes out the instances of x
X x = foo( vp, 0);
x = foo( x.a, 0);
x = foo( x.a, 0)
or
X x1 = foo( vp, 0);
X x2 = foo( x1.a, 0);
X x3 = foo( x2.a, 0)
doesn't matter. for instance the segfault happens because
X x2 = foo( x1.a, 0);
x1 was optimized out and the implementation tries to access the first argument , which is a null pointer.
回答1:
You can set the optimization level for a single function in GCC, too:
X foo(void *u, void *v) __attribute__((optimize("no-elide-constructors");
The optimize attribute is used to specify that a function is to be compiled with different optimization options than specified on the command line. Arguments can either be numbers or strings. Numbers are assumed to be an optimization level. Strings that begin with O are assumed to be an optimization option, while other options are assumed to be used with a -f prefix. You can also use the ‘#pragma GCC optimize’ pragma to set the optimization options that affect more than one function. See Function Specific Option Pragmas, for details about the ‘#pragma GCC optimize’ pragma.
This can be used for instance to have frequently-executed functions compiled with more aggressive optimization options that produce faster and larger code, while other functions can be compiled with less aggressive options.
https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html
You can also try the #pragma variant:
#pragma GCC push_options
#pragma GCC optimize ("no-elide-constructors")
X foo(void *u, void *v);
#pragma GCC pop_options
来源:https://stackoverflow.com/questions/33475315/disable-return-value-optimization-for-one-function