Array initialization in C

I have doubts about the following code snippet:

int main() { int array1 = {1,2,3,4,5}; //error in c++ , warning in c int array2[] = {1,2,3,4,5}; int array3[5] = {1,2,3,4,5}; } 

This piece of code gives an error in line 3 in c++ , but not in c ?

I know that array1 is actually int and array2 and array3 are arrays, so why does the c compiler not show an error, but just a warning: "extra elements in scalar initialization"

Is such a definition used and why does it apply in c ?

+19
c ++ c arrays
Oct 29 '14 at 10:23
source share
7 answers

Invalid C. See C11 6.7.9:

No initializer will attempt to provide a value for the object, and not contained in the initialized object.

I would suggest that you use gcc. Then, if you want your program to behave like a strict C standard, compile it as such:

 gcc -std=c11 -pedantic-errors 

gives

error: redundant elements in scalar initializer

+26
Oct 29 '14 at 10:32
source share

This is not valid in C. It has fewer code checks. This behavior is undefined.

From: C11 draft N1570; 6.7.9 Initialization

Constraints
2 No initializer will attempt to provide a value for an object not contained in the initialized object.
3 The type of object to be initialized must be an array of unknown size or the full type of an object that is not an array of variable length.

Definitely aborts restriction 2. Is int complete object type?

from J.2 application (undefined behavior):

An initializer for a scalar is neither a single expression, nor a single expression enclosed in curly braces (6.7.9).

additionally:
@James Kanze:

 prog.c:4:12: error: expected identifier or '(' before numeric constant int i = 1,2,3,4,5; ^ 

you can do this, but you need to make one expression:

 int i = (1,2,3,4,5); //need parenthesis, evaluates to 5, values 1-4 thrown away. 

Compiling with int , initialized with the initalizer list, generates a warning (in gcc):

 prog.c:5:2: warning: excess elements in scalar initializer [enabled by default] int j = {1,2,3,4,5}; ^ 

but it seems that the compiler is smart enough to initialize an int, not the next memory. demo

+15
Oct 29 '14 at 10:26
source share

It is valid in accordance with specification C.

Quote from section C11 6.7.9 (Initialization):

Syntax

 1 initializer: assignment-expression { initializer-list } { initializer-list , } 

Thus, an initializer can be either a direct expression ( assignment-expression above) or a list of initializers in brackets. The restrictions in this section of the standard do not limit this to "normal" (not an array or non-pointer) variables.

This allows you to write, for example.

 int a = { 1 }; 
+11
Oct 29 '14 at 10:32
source share

Like everyone else, I assume that the line you are thinking of is this:

 int array1 = {1,2,3,4,5}; 

In this case, there is no difference between C and C ++; the line may be legal in both languages, but that doesn’t mean what you think. In C and C ++, there is a statement that if a type is a scalar type ( int is), then the content {...} should be a single expression. And 1,2,3,4,5 can be interpreted as a single expression (with a comma operator); something like:

 int array1 = 1, 2, 3, 4, 5; 

clearly legal.

This is somewhat ambiguous, however, since in both languages ​​the grammar for this type of initialization does punctuation rather than an operator. So this is a matter of interpretation; this statement that the contents should be the only expression is a restriction on the grammar (which will lead to the comma becoming an operator) or a restriction on the results of the evaluation of the specified grammar. My intuitive feeling is that the second is intention, and this statement should lead to error. But the difference is not between C and C ++, but between the way compiler authors interpret the standard.

EDIT:

Rereading a little closer: in the C ++ standard, he clearly says that

If T is a scalar type, then the declaration of the form

     T x = {a};

equivalently

     T x = a;

Which does not leave much room for disassembly: in C ++, the expression seems clearly legal; it is only in C where there is some ambiguity.

+3
Oct 29 '14 at 11:54 on
source share

The correct way to initialize an array in C / C ++:

 int array2[] = {1,2,3,4,5}; 

Here, the square brackets actually tell the compiler that it is an array, a set of numbers in your case. In this initialization case, there is no need to specify the length of the array. The compiler will know.

The second way is to define an array and initialize it after it:

 int array3[5]; int *array = new int[5]; 

In this case, you need to tell the compiler what size the array will be. In addition, in the second case, you need to delete the memory manually.

+2
Oct 29 '14 at 10:32
source share

As your compiler says, this is not true for C. It is important to note that in the case of such "violation of restrictions" (the official term), the compiler can simply perform the diagnostics (which your compiler did) and continue.

This is why you should make sure your code compiles without any diagnostics.

+2
Oct 29 '14 at 13:12
source share

C is a low-level resolving language. This allows you to influence the pointer to int.

 int array1 = {1,2,3,4,5}; 

EDIT:

I had to test it under different compilers before writing stupid things.

This is rejected as an error by MSVC (2008).

Both gcc and clang issue a warning excess elements in scalar initializer and simply affect 1 on a .

+1
Oct 29 '14 at 10:33
source share



All Articles