Я недавно нашел эквивалент этого кода в нашей кодовой базе:
#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;
}
Запуск этого с g++ -std=c++11 -Wall -pedantic -Wextra test.cc
дает вывод (gcc версия 5.4.0)
5
10
Однако добавление флага -O3
дает результат
5
0
Это имеет смысл, так как мы возвращаем ссылку на m_a
, которая принадлежит rvalue A()
. Меня больше всего удивляет, что компилятор не жалуется на это. Сейчас мы решили эту проблему, предоставив две версии функции:
const int& a() & const { return m_a; }
int a() && const { return m_a; }
Это работает, но я немного волнуюсь, что у нас могут быть похожие проблемы в других местах кода. Есть ли какой-нибудь флаг компилятора, который я могу включить, чтобы предупредить об этом?