The following code compiles fine in Clang and outputs size of int [3]
array
#include <iostream>
int main()
{
const int (&a)[] = { 1, 2, 3 };
std::cout << sizeof a << std::endl;
}
However, in GCC the declaration compiles fine, but sizeof a
doesn't: apparently GCC refuses to "deduce" the array size and ends up with a
as a reference to const int []
type, which is incomplete.
What is the intended behavior in such initializations?
9.3.4/3 appears to be the relevant portion of the standard for such cases, but by itself it doesn't seem to answer this conclusively.
The standard is not entirely clear on this point, and I think GCC's interpretation is likely to be what WG21 intended, but I am not certain.
The relevant section of the standard is [dcl.array], which describes how to determine the type declared by a declaration in which a declarator contains the array-forming operator []
. I quote the relevant part:
An array bound may also be omitted when the declarator is followed by an initializer (11.6) or when a declarator for a static data member is followed by a brace-or-equal-initializer (12.2). In both cases the bound is calculated from the number of initial elements (say,
N
) supplied (11.6.1), and the type of the identifier ofD
is “array ofN
T
”.
It's not entirely whether this only applies to a declaration of an array itself, or whether it should also apply in the case of a reference to an array, since [dcl.array] must be recursively consulted when interpreting [dcl.ref] (which describes the &
and &&
operators). However, I think that the latter interpretation should be rejected, as we would not expect the initializer to result in a bound being deduced when the []
is buried deeper in the declarator. To wit, consider the contrived example:
int (*a[1])(const int (&)[]) = {0};
Here GCC and Clang agree, and I think common sense agrees also, that the type of a
is int (*[1])(const int (&)[])
, and not int (*[1])(const int (&)[1])
: the fact that a
possesses an initializer does not cause the inner array bound to be deduced.
Based on this, I would argue that GCC is correct in not deducing the array bound in your code, so that a
has type const int (&)[]
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With