无法从多维数组的初始值设定项中推导出边界

时间:2016-01-24 04:19:34

标签: c++ arrays language-lawyer array-initialization

以下代码无法编译:

int main() {
  int a[][] = { { 0, 1 },
                { 2, 3 } };
}

产生的错误消息是

error: declaration of 'a' as multidimensional array must have bounds for all dimensions except the first
int a[][] = { { 0, 1 },
           ^

这是由标准规定的吗?如果是这样,为什么呢?我认为在这里推算界限非常容易。

1 个答案:

答案 0 :(得分:3)

  

这是由标准指定的吗?

嗯,是的。

  

§8.3.4/ 3当几个“数组”规范相邻时,a   创建多维数组类型;只有第一个常数   可以省略指定数组边界的表达式。在   除了不完整的对象类型的声明之外   允许,在某些情况下可以省略数组绑定   声明函数参数(8.3.5)。数组绑定也可以   当声明符后跟初始值设定项(8.5)时,将省略。   在这种情况下,边界是从初始数量计算的   提供的元素(例如,N)(8.5.1),以及标识符的类型   D的“N T数组”。此外,如果有前一个   声明与该界限相同的实体的声明   指定时,省略的数组绑定与其中的相同   早期声明,类似于静态数据的定义   班级成员。

  

如果是这样,为什么会这样?

首先,不能用不完整的类型(例如void)构造数组。未知边界的数组是这些不完整类型之一:

  

§8.3.4/ 1 ...数组类型的对象包含一个连续分配的对象   类型为N的非空T子对象集。除非如下所述,否则   省略常量表达式,D标识符的类型   是“ derived-declarator-type-list 未知范围T”的数组,   不完整的对象类型...

     

§8.3.4/ 2可以从一种基本类型构造一个数组   (除了void),从指针,指向成员的指针,从   class,枚举类型或其他数组。

此外:

  

§3.9已声明但未定义的类,枚举   键入某些上下文(7.2),或未知大小的数组或   不完整的元素类型,是未完全定义的对象   输入 45 ...

     

45)未完全定义的实例的大小和布局   对象类型未知。

  

我认为在这里演绎界限非常容易。

初学者犯了一个常见错误,即编译器具有神奇的力量。编译器使用已经的信息,它不会凭空创建信息。如果您要求它创建一个未知大小的对象,它根本无法这样做。请参阅以下示例:

  

只能省略最里面的尺寸。元素的大小   推导出为数组变量赋予的类型的数组。该   因此,元素的类型必须具有已知的大小。

     
      
  • char a[] = { ... };包含大小 1(8位)的元素(例如a[0],且大小未知。
  •   
  • char a[6] = { ... };的元素大小 1,大小为6。
  •   
  • char a[][6] = { ... };包含元素(例如a[0],这是一个数组)大小 6,且大小未知。
  •   
  • char a[10][6] = { ... };的元素大小 6.并且大小为60。
  •   
     

不允许:

     
      
  • char a[10][] = { ... };将有10个未知大小
  •   
  • char a[][] = { ... };将包含未知数量未知大小的元素。
  •   

Source