9

I was under the impression that variable-size array declarations were not possible in C89. But, when compiling with clang -ansi I am able to run the following code:

double array[] = { 0.0, 1.0, 2.0, 3.0, 4.0 };
double other_array[sizeof(array)] = { 0.0 };

What is going on here? Is that not considered a variable-size array declaration?

  • 1
    There are no variable size arrays in C89, so it could not be considered a variable size array declaration. . – M.M Aug 25 '15 at 22:17

3 Answers3

8

In ANSI C89 a.k.a. ISO C90, the sizeof operator yields an integer constant, which is suitable for array dimensions. Function calls, for example, are not.

I'd like to add another remark, since I believe the code as-is has a problem that might get overlooked.

If the other_array is declared as

double other_array[sizeof(array)];

it will neither have the same number of elements, nor the same size (that would only be true for array of char) as array[]. If the intent is to declare a second array with the same number of elements (regardless of type), use this:

double other_array[sizeof(array)/sizeof(*array)];
Gilles 'SO- stop being evil'
  • 104,111
  • 38
  • 209
  • 254
Jens
  • 69,818
  • 15
  • 125
  • 179
  • 3
    Not my downvote, but this is not an answer to the question. This should be a comment. – Jens Gustedt Aug 25 '15 at 21:21
  • @JensGustedt Fair enough. But I tried to actually *understand* what the code was supposed to achieve, see more than the technical question, uncover why someone would want another array the number of elements were one for each byte in a double array. That does not look right and the comments are simply too limited when it comes to formatting. Maybe I should repeat the technical answer a third time to conform to the answer expectation. – Jens Aug 25 '15 at 21:55
5

That is because result of sizeof operator is constant expression, so it does not qualify for VLA, just like the following declaration:

int other_array[5];

cannot be variable length array either. From C11 (N1570) §6.6/p6 Constant expressions (emphasis mine going forward):

An integer constant expression117) shall have integer type and shall only have operands that are integer constants, enumeration constants, character constants, sizeof expressions whose results are integer constants, _Alignof expressions, and floating constants that are the immediate operands of casts.

For sake of completeness, the sizeof operator does not always results into constant expression, though this only affects post-C89 standards (in C11 VLAs were made optional). Referring to §6.5.3.4/p2 The sizeof and _Alignof operators:

If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant.

Grzegorz Szpetkowski
  • 36,988
  • 6
  • 90
  • 137
3

First, let's see the criteria for an array (not being) a VLA. C11 doc, chapter §6.7.6.2,

[...] If the size is an integer constant expression and the element type has a known constant size, the array type is not a variable length array type; [...]

Coming to your case, sizeof is a compile-time operator, so it produces a value that is considered compile time constant expression. An array definition, whose size is specified as a compile time constant expression is not a VLA. So, in your code,

int other_array[sizeof(array)]

is not a VLA.

Regarding the sizeof operator result, from C11, chapter §6.5.3.4, (emphasis mine)

The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. [...] otherwise, the operand is not evaluated and the result is an integer constant.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • 2
    In C11 `sizeof` is not a "compile-time operator" and sometimes does not produce constant expression. (Although OP was asking about C89) – M.M Aug 25 '15 at 22:13