c++ - 无法从多维数组的初始值设定项推断边界

标签 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 },
           ^

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

最佳答案

Is this specified by the standard?

嗯,是的。

§8.3.4/3 When several “array of” specifications are adjacent, a multidimensional array type is created; only the first of the constant expressions that specify the bounds of the arrays may be omitted. In addition to declarations in which an incomplete object type is allowed, an array bound may be omitted in some cases in the declaration of a function parameter (8.3.5). An array bound may also be omitted when the declarator is followed by an initializer (8.5). In this case the bound is calculated from the number of initial elements (say, N) supplied (8.5.1), and the type of the identifier of D is “array of N T”. Furthermore, if there is a preceding declaration of the entity in the same scope in which the bound was specified, an omitted array bound is taken to be the same as in that earlier declaration, and similarly for the definition of a static data member of a class.

If so, why is that?

一方面,不能从不完整的类型(例如 void)构造数组。未知边界的数组是不完整类型之一:

§8.3.4/1 ... An object of array type contains a contiguously allocated non-empty set of N subobjects of type T. Except as noted below, if the constant expression is omitted, the type of the identifier of D is “ derived-declarator-type-list array of unknown bound of T”, an incomplete object type. ...

§8.3.4/2 An array can be constructed from one of the fundamental types (except void), from a pointer, from a pointer to member, from a class, from an enumeration type, or from another array.

此外:

§3.9 A class that has been declared but not defined, an enumeration type in certain contexts (7.2), or an array of unknown size or of incomplete element type, is an incompletely-defined object type.45 ...

45) The size and layout of an instance of an incompletely-defined object type is unknown.

I think deducing bounds here would be very easy.

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

Only the innermost dimension can be omitted. The size of elements in an array are deduced for the type given to the array variable. The type of elements must therefore have a known size.

  • char a[] = { ... }; has elements (e.g. a[0]) of size 1 (8bit), and has an unknown size.
  • char a[6] = { ... }; has elements of size 1, and has size 6.
  • char a[][6] = { ... }; has elements (e.g. a[0], which is an array) of size 6, and has an unknown size.
  • char a[10][6] = { ... }; has elements of size 6. and has size 60.

Not allowed:

  • char a[10][] = { ... }; would have 10 elements of unknown size.
  • char a[][] = { ... }; would have an unknown number of elements of unknown size.

Source

关于c++ - 无法从多维数组的初始值设定项推断边界,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34972172/

相关文章:

c++ - 需要一些帮助解决两个错误 (C++)

arrays - 计算数组中的索引有助于算法

rust - 为什么 `Idx` 特征的 `Index` 类型参数允许取消大小?

java - 当使用不相关的接口(interface)类型调用时,为什么编译器会选择带有类类型参数的泛型方法?

c# - 我想在整数数组的连续子集中找到公共(public)数字的最大频率

c++ - 对结构成员的临时绑定(bind)引用

c++ - 如何一次从文本文件中读取一个字符

c++ - std::cout<< ' ' <<std::endl;输出一个数字;为什么?

C++ 错误 : no matching constructor for initialization of "my:Library" with Clang 11. 0.3

javascript - 关于确定数组中存储的最高值的不同方法的一些问题(加上输出消息问题)