c++ - What's happening with the snippet below in a release build? -
the code below generates dangling reference can seen in warning emitted compiler , fact destructor a
object in function g()
invoked before function returns. 1 can verify in main()
after "using stack", returned reference has garbage, @ least in debug build. couldn't reproduce same behavior in release build. why that? kind of optimization compiler doing here give impression reference r
ok?
#include <iostream> struct a{ a(int i) : i(i) { std::cout << "ctor\n"; } a(const a& a) { = a.i; std::cout << "copy ctor\n"; } ~a() { std::cout << "dtor\n"; } int i; }; a& g(int i) { x(i); return x; } int main() { const a& r = g(1); std::cout << "using stack\n"; std::cout << r.i << '\n'; // r.i has garbage in debug, not in release build. }
ps. argue against nrvo, function doesn't return a
object.
edit: in response mark tolonen. if include these expressions after const a& r = g(1);
release build doesn't show garbage in std::cout << r.i << '\n';
std::cout << "using stack ...................................................................................................................\n"; std::cout << "using stack ...................................................................................................................\n"; std::cout << "using stack ...................................................................................................................\n"; std::cout << "using stack ...................................................................................................................\n";
here's speed-optimized (/o2 compiler switch) release build of visual studio 2012 64-bit when runs code , prints out one:
int main() { 000000013f7c7e50 sub rsp,28h const a& r = g(1); 000000013f7c7e54 lea rdx,[string "ctor\n" (013f83da4ch)] 000000013f7c7e5b lea rcx,[std::cout (013f85faa0h)] 000000013f7c7e62 call std::operator<<<std::char_traits<char> > (013f7c1500h) 000000013f7c7e67 lea rdx,[string "dtor\n" (013f83da54h)] 000000013f7c7e6e lea rcx,[std::cout (013f85faa0h)] 000000013f7c7e75 call std::operator<<<std::char_traits<char> > (013f7c1500h) std::cout << "using stack\n"; 000000013f7c7e7a lea rdx,[string "using stack\n" (013f83da60h)] 000000013f7c7e81 lea rcx,[std::cout (013f85faa0h)] 000000013f7c7e88 call std::operator<<<std::char_traits<char> > (013f7c1500h) std::cout << r.i << '\n'; // r.i has garbage in debug, not in release build. 000000013f7c7e8d lea rcx,[std::cout (013f85faa0h)] 000000013f7c7e94 mov edx,1 000000013f7c7e99 call std::basic_ostream<char,std::char_traits<char> >::operator<< (013f7c1384h) 000000013f7c7e9e mov dl,0ah 000000013f7c7ea0 mov rcx,rax 000000013f7c7ea3 call std::operator<<<std::char_traits<char> > (013f7c10ebh)
note doesn't bother create , destroy a
object. call cout
4 times. each time, rdx
holds object print. first 3 print strings "ctor\n", "dtor\n", , "using stack\n". last 1 looks prints integer in edx
1
.
the compiler can undefined behavior. prints besides 1 space-optimized (/o1 compiler switch), or op found, not-optimized (/od).
Comments
Post a Comment