我的程序中有两个源文件。
数组定义在A.cpp.
// compiler: MSVC2005 SP2
// A.cpp
// defines an array of type "int [100]"
int a[100] = {3};
它用于B.cpp.
// B.cpp
// declares an array of type "int []"
extern int a[];
int main()
{
// prints 3 correctly
cout << a[0] << endl;
return 0;
}
AFAIK,如果使用声明的标识符,链接器找不到声明的任何匹配定义,则会引发错误。这里,int [] and 整数 [100]显然,这是两种不同的类型。
在这种情况下,为什么没有任何链接错误?是否由以下保证标准在声明/定义匹配期间数组大小是微不足道的?或者它只是特定于实现的?引用自标准如果有的话将不胜感激。
Edit:iammind在他的回答中提到链接器可以正确运行(他的编译器是gcc)即使声明和定义之间的类型不匹配。它是标准所要求的还是只是 gcc 的一种方式?我想这是一个更重要的问题需要弄清楚。
在 C 和 C++ 中,对象的声明a
不完整类型将匹配对象的定义a
其中类型已完成。您所观察到的只是说明了这样一个事实:在 C++ 中,您可以在非定义声明中使用不完整类型。但是一旦获得定义,类型就必须是完整的。
此行为不限于数组。例如,您可以声明
extern class X x;
对于一个完全未知的班级X
,然后,当class X
已经完全定义了,你可以定义
X x;
这将与上面的声明相匹配。
您的阵列也会发生同样的情况。首先声明一个不完整类型的对象
extern int a[];
然后用完整类型定义它
int a[100];
这里的类型确实不匹配。然而,C++ 语言从不要求它们匹配。例如,3.9/7明确指出
数组对象的声明类型可能是未知大小的数组
因此在翻译单元中的某一点是不完整的并且
稍后完成;这两个点的数组类型(“数组
T 的未知边界”和“N T 的数组”)是不同的类型。
代表着the same数组对象最初可以具有不完整的类型,但稍后会获取完整的类型。 (另请参见 3.9/7 中的示例)。当然,这并不意味着您可以声明a
as an int
然后将其定义为double
。同样,您在这里拥有的唯一与类型相关的自由是完成不完整的类型。不再。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)