Failed to deduce bounds from initializer for multi-dimensional arrays

江枫思渺然 提交于 2019-12-11 00:32:39

问题


This following code does not compile:

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

The error message produced is

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? If so, why is that? I think deducing bounds here would be very easy.


回答1:


Is this specified by the standard?

Well, yeah.

§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?

For one thing, an array can't be constructed from an incomplete type (void for example). An array of unknown bound is one of those incomplete types:

§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.

Furthermore:

§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.

There is a common mistake beginners make, that the compiler has magical powers. The compiler works with information it already has, it does not create information out of thin air. If you asked it to create an object of unknown size, it simply would not be able to do so. See the following examples:

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



来源:https://stackoverflow.com/questions/34972172/failed-to-deduce-bounds-from-initializer-for-multi-dimensional-arrays

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!