Во время игры с примерами из Modern С++ я написал следующий код.
#include <string>
#include <iostream>
static int count = 0;
class Counter
{
public:
Counter() { ++count; };
Counter(Counter& r) { ++count; };
Counter(Counter&& r) { ++count; };
~Counter() { --count; };
void foo() {};
};
decltype(auto) foo_warn()
{
Counter c;
return (c); // Warning about returning local reference
}
decltype(auto) foo_no_warn()
{
Counter c;
return 1==1 ? c : c; // No warning, still local reference returned
}
int main()
{
Counter& a = foo_warn();
Counter& b = foo_no_warn();
std::cout << count << std::endl; // prints 0
a.foo();
b.foo();
return 0;
}
Код, скомпилированный с помощью команды:
g++-6 -std=c++14 -Wall -O0 decl_fail.cpp -o decl_fail
Вывод:
g++-6 -std=c++14 -Wall -O0 decl_fail.cpp -o decl_fail
decl_fail.cpp: In function ‘decltype(auto) foo_warn()’:
decl_fail.cpp:19:10: warning: reference to local variable ‘a’ returned [-Wreturn-local-addr]
Counter a;
^
Мне ясно, что decltype(auto)
возвращает ссылку для выражений (но все же не интуитивно), поэтому a
и b
являются недопустимыми ссылками (доказано count==0
).
Вопрос в том, почему компилятор не предупредил меня об этом в foo_no_warn
?
Я только что нашел ошибку в компиляторе, или это объясняет поведение?