Why can't I use a constant int to declare an array AND initialize it in C?

Viewed 157

Option 1: use #define

#define kSize 5
int arr1[kSize] = {1,2,3,4,5};

--> OK.

Option 2: use an enum

enum { eSize = 5 };
int arr2[eSize] = {1,2,3,4,5};

--> OK.

But, a const int cannot be used:

const int cSize=5;
int arr3[cSize] = {1,2,3,4,5};

--> FAIL.

why?

1 Answers

A variable with the const qualifier does not qualify as an integer constant expression. This makes the array a variable length array (VLA) which cannot be initialized.

Section 6.7.6.2p4 of the C standard describing Array Declarators states:

If the size is not present, the array type is an incomplete type. If the size is * instead of being an expression, the array type is a variable length array type of unspecified size,which can only be used in declarations or type names with function prototype scope such arrays are nonetheless complete types. 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; otherwise, the array type is a variable length array type. (Variable length arrays are a conditional feature that implementations need not support; see 6.10.8.3.)

So for an array to not be a variable length array its size must be an integer constant expression. This is defined in section 6.6p6:

An integer constant expression 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. Cast operators in an integer constant expression shall only convert arithmetic types to integer types, except as part of an operand to the sizeof or _Alignof .operator

A #define definition is replaced by the preprocessor before the compilation phase, so in your first case kSize is exactly the same as the constant 5. The above passage also states than an enum constant qualifies as an integer constant expression, so this makes your second case OK. The third case uses a const qualified variable which is not included above in the definition of an integer constant expression, so this makes it a variable length array.

Section 6.7.9p3 then dictates what can be initialized:

The type of the entity to be initialized shall be an array of unknown size or a complete object type that is not a variable length array type.

And as stated above a VLA cannot be initialized.

Related