Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GCC's decltype(auto) doesn't conform to the standard?

I tried compiling this C++ code under GCC 8.2 with different options and it always succeeds, produces no warnings and outputs true:

int && a = 123;
decltype(auto) b = a;

std::cout << std::boolalpha << std::is_same<decltype(b), int&>::value;

Meanwhile, the same code will not compile in Clang, and if my understanding of the standard is correct, that's the standard-conforming behavior.

cppreference on decltype:

If the argument is an unparenthesized id-expression or an unparenthesized class member access expression, then decltype yields the type of the entity named by this expression.

cppreference on decltype(auto):

If the declared type of the variable is decltype(auto), the keyword auto is replaced with the expression (or expression list) of its initializer, and the actual type is deduced using the rules for decltype.

Therefore, decltype(auto) should yield int&&. And since a is an lvalue, it should not bind to b, resulting in a compilation error.

So does GCC fail to conform to the standard or is there something I'm missing?

like image 484
Ivan Avatar asked Nov 18 '18 07:11

Ivan


1 Answers

Your reasoning is sound. And I think I see where GCC is tripping.

The wording for decltype(auto) says that auto is replaced with the expression in the initializer. Which according to GCC would imply your code is not equivalent to

decltype(a) b = a;

But rather it is equivalent to

decltype((a)) b = a;

But that is wrong. The initializer is "an unparenthesized id-expression", so the rules in [dcl.type.simple] for unparenthesized id-expressions should apply normally. The type of b needs to be deduced as int&&.


And as @Aconcagua was able to dig up, this is a known GCC bug.

like image 195
StoryTeller - Unslander Monica Avatar answered Oct 06 '22 11:10

StoryTeller - Unslander Monica