以下代码在Clang中可以正常编译,并输出mosaicplot
数组的大小
int [3]
但是,在GCC中,该声明可以很好地编译,但是#include <iostream>
int main()
{
const int (&a)[] = { 1, 2, 3 };
std::cout << sizeof a << std::endl;
}
不能编译:显然,GCC拒绝“推导”数组大小,并以sizeof a
作为对a
的引用类型,不完整。
这种初始化的预期行为是什么?
9.3.4/3似乎是此类情况下标准的相关部分,但就其本身而言,似乎并不能得出结论。
答案 0 :(得分:1)
关于这一点,标准尚不完全清楚,我认为GCC的解释很可能就是WG21的意图,但我不确定。
标准的相关部分是[dcl.array],它描述了如何确定由声明所声明的类型,其中声明符包含数组形成运算符[]
。我引用相关部分:
当声明符后跟 initializer (11.6)或静态数据成员的声明符后跟 brace-or-equal-时,也可以省略数组绑定初始化程序(12.2)。在这两种情况下,边界都是根据提供的初始元素(例如
N
)的数量(11.6.1)来计算的,D
标识符的类型是“N
的数组T
”。
这并不完全是仅适用于数组本身的声明,还是在引用数组时也应适用,因为在解释[dcl.ref]时必须递归地咨询[dcl.array] ](描述&
和&&
运算符)。但是,我认为应该拒绝后者的解释,因为当[]
被深深地埋在声明器中时,我们不会期望初始化器会导致推导边界。明智地考虑一下人为的例子:
int (*a[1])(const int (&)[]) = {0};
这里是GCC和Clang agree,我认为常识也同意,a
的类型是int (*[1])(const int (&)[])
,而不是int (*[1])(const int (&)[1])
:{{ 1}}具有一个初始化程序,不会导致内部数组的绑定被推导。
基于此,我认为GCC在不推导代码中绑定的数组方面是正确的,因此a
的类型为a
。