I recently found the equivalent of this code in our code base:
#include <iostream>
struct A
{
A(int a) : m_a(a) {}
const int& a() const { return m_a; }
private:
int m_a;
};
int main()
{
int a = A(5).a(); // OK
const int& a_ref = A(10).a(); // Not OK
std::cout << "a=" << a << std::endl;
std::cout << "a_ref=" << a_ref << std::endl;
}
Running this with g++ -std=c++11 -Wall -pedantic -Wextra test.cc
gives output (gcc version 5.4.0)
5
10
However, adding the -O3
flag gives the result
5
0
This makes sense, as we're returning a reference to m_a
which is belongs to the rvalue A()
. I'm mostly surprised that the compiler does not complain about this. Right now we've solved it by giving two versions of the function:
const int& a() & const { return m_a; }
int a() && const { return m_a; }
This works, but I'm a little worried that we might have similar issues at other places in the code. Are there any compiler flag that I can turn on that would warn for this?