在涉及数组时,不应该声明与其定义匹配吗?

Eri*_*c Z 8 c++ arrays

我的程序中有两个源文件.

数组在A.cpp中定义.

// compiler: MSVC2005 SP2    
// A.cpp

// defines an array of type "int [100]"
int a[100] = {3};
Run Code Online (Sandbox Code Playgroud)

它用于B.cpp.

// B.cpp

// declares an array of type "int []"
extern int a[];

int main()
{
  // prints 3 correctly
  cout << a[0] << endl;
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

AFAIK,如果使用声明的标识符,如果找不到声明的任何匹配定义,则链接器将引发错误.这里,int []int [100]显然是两种不同的类型.

在这种情况下,为什么没有链接错误?标准是否保证在声明/定义匹配期间数组大小是微不足道的?或者它只是特定于实现?如果有的话,将赞赏标准的引用.

编辑: iammilind在他的回答中提到链接器可以正确运行(他的编译器是gcc),即使声明和定义之间的类型不匹配.是标准要求还是gcc的方式?我想这是一个非常重要的问题.

AnT*_*AnT 7

在C和C++中a,不完整类型的对象的声明将匹配a类型完整的对象的定义.您观察到的只是说明了在C++中允许在非定义声明中使用不完整类型的事实.但是一旦达到定义,类型必须完整.

此行为不限于数组.例如,您可以声明

extern class X x;
Run Code Online (Sandbox Code Playgroud)

对于一个完全未知的类X,然后,当class X已经完全定义时,您可以定义

X x;
Run Code Online (Sandbox Code Playgroud)

这将符合上述声明.

您的阵列也会发生同样的事情.首先声明一个不完整类型的对象

extern int a[];
Run Code Online (Sandbox Code Playgroud)

然后用完整的类型定义它

int a[100];
Run Code Online (Sandbox Code Playgroud)

这里的类型确实不匹配.但是,C++语言从未要求它们匹配.例如,3.9/7明确说明

声明的数组对象类型可能是一个未知大小的数组,因此在翻译单元中的某一点不完整,稍后会完成; 这两个点的数组类型("T的未知边界数组"和"NT数组")是不同的类型.

这意味着同一个数组对象最初可能具有不完整的类型,但稍后会获得完整的类型.(另见3.9/7中的例子).当然,这并不意味着你可以声明a为a int然后将其定义为a double.你在这里唯一与类型相关的自由是完成一个不完整的类型.不再.