3

I would like to know what happens when there are more initializers than array size, e.g. :

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

Of course, my compiler warns it. I expected undefined behavior, but I didn't find any clause about it in C11 standard. So, did I miss something ?

M.M
  • 138,810
  • 21
  • 208
  • 365
md5
  • 23,373
  • 3
  • 44
  • 93
  • What compiler is this? It errors on VS2010. – Mysticial Aug 29 '12 at 16:53
  • That shouldn't even compile : http://ideone.com/gWs4i – Nawaz Aug 29 '12 at 16:55
  • gcc 4.4.5, `-Wall -Wextra -pedantic`, prints just a warning. – md5 Aug 29 '12 at 16:55
  • 2
    The second paragraph in 6.7.9 C11 goes *No initializer shall attempt to provide a value for an object not contained within the entity being initialized*. I think it prohibits having more initializers than array elements. – cnicutar Aug 29 '12 at 16:57
  • Why would you expect undefined behavior for an error that the compiler can readily detect? – Jim Balter Aug 29 '12 at 23:36
  • @Jim Balter: Sometimes, my compiler warns even if there are no wrong behavior (e.g. a variable not used). – md5 Aug 30 '12 at 06:58
  • That doesn't pertain to my question. – Jim Balter Aug 30 '12 at 12:34
  • @JimBalter Considering that compiling a source file that does not end in a newline character, or a file where a string literal does not end at the end of the line, are both undefined behavior, I find the question entirely legitimate regardless of what compilers accept. – Pascal Cuoq Sep 02 '12 at 09:54
  • @PascalCuoq I have no idea what "question" you're referring to that anyone said isn't "legitimate". *I* asked a question, about an *expectation*. The unrelated cases you refer to actually have reasons that have nothing to do with the ability of the compiler to detect them, but rather allow for certain sorts of implementations that were known to the standards committee. – Jim Balter Sep 03 '12 at 20:04
  • @JimBalter OP asks whether something is UB. You comment by rhetorically asking why it should be, since it's readily detectable. I point out that some readily detectable patterns are UB, although they could easily have been made syntax errors. This makes the OP's question legitimate IMHO (your rhetorical question implies it isn't). The “unrelated cases” I mention are related by virtue of being readily detectable and UB. The standards committee had its reasons, but since the OP was not there at the time of the discussion, he can legitimately ask whether another readily detectable pattern is UB – Pascal Cuoq Sep 03 '12 at 21:08
  • @PascalCuoq My question was not rhetorical and I never said that any question of the OP was not legitimate. Again, my point was about the OP's **expectation**. Enjoy your debate with a strawman, but I'm out of here. – Jim Balter Sep 04 '12 at 17:16

3 Answers3

6

The code is ill-formed in both C and C++.

C++11 §8.5.1[dcl.init.aggr]/6 states:

An initializer-list is ill-formed if the number of initializer-clauses exceeds the number of members or elements to initialize.

C11 §6.7.9/2 states:

No initializer shall attempt to provide a value for an object not contained within the entity being initialized.

James McNellis
  • 348,265
  • 75
  • 913
  • 977
1

I took a look at the assembler gcc generated for your example, and it looks like it takes the "safe" route; it simply doesn't load values past the size of the array:

void main() {
    int t[3] = { 1, 2, 3, 4 };
}

Generates the following assembly:

main:
    pushl %ebp
    movl  %esp, %ebp
    subl  $16, %esp
    movl  $1, -12(%ebp)
    movl  $2, -8(%ebp)
    movl  $3, -4(%ebp)
    leave
    ret

This was generated with gcc 4.4.3.

Ethan Brown
  • 26,892
  • 4
  • 80
  • 92
  • For the compiler to allocate three elements but store four wouldn't just be "unsafe", it would be perverse, going out of its way to punish the programmer for providing too many initializers. – Jim Balter Aug 29 '12 at 23:41
0

Well it depends on your compiller. Some won't even let you build with that, Visual Express gives:

error C2078: too many initializers

Where as gcc allows it to fly but warns you there are too many elements... I don't think there is a expected behavior given this case since it's undefined, but it won't work for sure.

Ex:

int t[3] = { 1, 2, 3, 4 }; 
int i;

for(i = 0; i< 5; i++){
    printf("val = %d\n", t[i]);}

val = 1
val = 2
val = 3
val = 4
val = 134513760

I didn't go into disasembly, but I'm pretty sure it's just running into other data at the end.

Mike
  • 47,263
  • 29
  • 113
  • 177
  • Well considering that i[4] isn't even defined in the initializer, I'm not exactly surprised? the fact that it prints out i[3] properly is amazing in and of itself but shouldn't be expected as it is undefined. – ardent Aug 29 '12 at 17:24
  • Yeah, I think it was a lucky run. – Mike Aug 29 '12 at 17:32