Answer 1 of the post How to declare array with auto works fine:
template<typename T> using unsized_raw_array = T[];
auto &&z = unsized_raw_array<int>{1, 2, 3};
Trying out the same but without the double ampersand (&&
) results in different behavior of clang and gcc:
template<typename T> using unsized_raw_array = T[];
auto z = unsized_raw_array<int>{1, 2, 3};
I expected this to be an error because it is an rvalue (universal/forwarding/temporary-object) reference and the double ampersand is missing (&&
). And that is what happens with gcc 6.3.0:
error: taking address of temporary array
However, clang 3.9.1 compiles and executes it successfully, allowing printing the values of the array in the next statements. I only get this warning (in some scenarios I don't even get the warning):
warning: pointer is initialized by a temporary array, which will be destroyed at the end of the full-expression [-Waddress-of-array-temporary]
Which compiler is correct?
Clang is correct; see [conv.array]:
An lvalue or rvalue of type “array of
N
T
” or “array of unknown bound ofT
” can be converted to a prvalue of type “pointer toT
”. The result is a pointer to the first element of the array.
Even if the array is a temporary, and therefore a prvalue, it is legal to perform the array-to-pointer conversion on it.
It appears that the restriction on converting array prvalues into pointers was introduced in a patch that resolved gcc bug 53220. It seems that a consensus emerged on the thread that allowing the conversion was dangerous since initializing a pointer variable from the array would not extend the lifetime of the array. However, treating such code as though it is ill-formed is not the correct solution, since, as pointed out later in the thread, it is possible to use this conversion in a safe way, e.g., if the array is being passed to a function that takes a pointer (and therefore will live until the function returns).
You would probably have to file a new bug against gcc in order to get them to fix the issue.