在a.h中,我错误地创建了一个没有extern
关键字的数组,这会产生一个暂定的定义
a.h:
MyStruct myArrayOfStructs [];
然后在a.cpp中定义该数组
a.cpp:
MyStruct myArrayOfStructs[CONSTANT];
令人惊讶的编译。
为什么编译器不抱怨重新定义?
答案 0 :(得分:6)
这完全有效。第一个(.h
)表示某处存在一个数组,但没有实例化它。
第二个分配它。
答案 1 :(得分:2)
您可以使用暂定定义来引用暂定定义,在这种情况下,先前的暂定定义被视为外部定义。在这种情况下,一个是完整的而另一个是不完整类型的事实并不是真正令人担忧的事实。
int i;
int i;
是合法代码。
int i = 5;
int i = 6;
不是合法代码,因为第一个不再是暂定的定义。
答案 2 :(得分:2)
这是非法的C ++,正如您所料。
3.1 / 2:
声明是一个定义,除非它声明一个函数而没有指定函数体,它包含
extern
说明符或 linkage-specification 既不是初始值设定项也不是函数体,它在类定义中声明了一个静态数据成员,它是一个类名声明,它是一个不透明的-enum-declaration ,它是 template-parameter ,它是函数声明符中的参数声明,它不是声明符 em> of a function-definition ,或者是typedef
声明, alias-declaration , using-declaration , static-assert-declaration ,属性声明,空声明, using-directive ,显式实例化声明,或声明不是定义的显式特化。
这些例外都不适用,因此头文件中的行是一个定义。
3.1 / 5:
如果任何对象的定义赋予对象不完整的类型,程序就会格式不正确。
也许你的编译器正在提供"暂定声明"来自C的行为作为扩展。
clang ++ says"错误:数组类型变量的定义需要显式大小或初始化程序"