gpt4 book ai didi

c++ - 空数组声明 - 奇怪的编译器行为

转载 作者:可可西里 更新时间:2023-11-01 16:40:05 28 4
gpt4 key购买 nike

我在我必须维护的项目中发现了一段看起来很奇怪的代码。类的一个空数组成员不会导致编译器错误。我已经使用 MSVC 10.0 测试了此类代码的一些变体:

template<class T> struct A {
int i[];
}; // warning C4200: nonstandard extension used : zero-sized array in struct/union

template<class T> struct B { static int i[]; };
template<class T> int B<T>::i[];

struct C {
int i[];
}; //warning C4200: nonstandard extension used : zero-sized array in struct/union

template<class T> struct D { static int i[]; };
template<class T> int D<T>::i[4];
template<> int D<int>::i[] = { 1 };


int main()
{
A<void> a;
B<void> b;
C c;
D<void> d0;
D<int> d1;

a.i[0] = 0; // warning C4739: reference to variable 'a' exceeds its storage space

b.i[0] = 0; // warning C4789: destination of memory copy is too small

c.i[0] = 0; // warning C4739: reference to variable 'c' exceeds its storage space

int i[]; // error C2133: 'i' : unknown size

d0.i[0] = 0; // ok
d0.i[1] = 0; // ok

return 0;
}

int i[] 处的错误消息对我来说绝对明智。用类 D 显示的代码是格式良好的标准 C++。但是 ABC 类是什么?该类中的成员变量int i[]是什么类型?

最佳答案

编辑:

您的疑问由 definition of the extension to the language 解释,它允许在结构/union 的末尾使用零大小的数组。我没有尝试过,但如果您在零大小数组之后声明另一个成员,它应该会失败。

所以,如果你在栈上分配一个变量,你必须知道它的大小;该规则的异常(exception)是在结构/union 的末尾分配数组时,可能会出现一些 C 典型的技巧。

在 C++ 中,这会引发警告,因为默认的复制构造函数和赋值运算符可能无法工作。

上一个答案:

编译器会警告您您正在尝试定义 零大小的数组。这在标准 C/C++ 中是不允许的。

让我们逐个类地查看差异。

在 D 类中:

template<class T> struct D { static int i[]; };

之所以有效,是因为您只是在声明静态成员变量的类型。为此链接,您还需要像您一样在定义语句中定义实际数组:

 template<>        int D<int>::i[] = { 1 };

在这里您还可以通过初始化程序指定数组的大小。

对于 B 类,您正在做类似的事情,但定义是:

 template<class T> int B<T>::i[];

即,您没有指定大小并收到警告。

对于 A 类,更多的是相同的,您正在定义一个没有大小的数组类型的成员变量。

关于c++ - 空数组声明 - 奇怪的编译器行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6607160/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com