0

I was trying to play with array initializations in a for loop in c.

Here is the program I tried :

#include<stdio.h>
int main(){
for(int i=0;i<3;i++){
    for(int j=0;j<3;j++){
        int br[10]={0};
        printf("%d\n", br[-1]);
    }
 }

 return 0;
}

The results of this code when compiled with gcc are:

0 1 2 0 1 2 0 1 2

The same program when compiled with clang ,the results are:

0 0 0 0 0 0 0 0 0

If I tweak the program a bit by making a array initialization before starting of second loop:

#include<stdio.h>


int main(){
 for(int i=0;i<3;i++){
    int ar[10]={0};
    for(int j=0;j<3;j++){
        int br[10]={0};
        printf("%d\n", br[-1]);
    }
 }

 return 0;
}

I get output as 0 0 0 0 0 0 0 0 0 for both gcc and clang

Can anyone explain what exactly is happening here,when I try to access a negative index why are these results showing up with these two different compilers(gcc and clang) and why is another array initialization before second loop changing everything.

satishdd
  • 19
  • 3
  • 3
    `br[-1]` is [Undefined Behavior](https://en.wikipedia.org/wiki/Undefined_behavior).... That's all – LPs Dec 06 '16 at 13:31
  • I don't think so. I think it has something to do with memory allocations. – satishdd Dec 06 '16 at 13:33
  • 1
    No, it's UB, pure and simple. The compiler reserves the right to eat your cat. – Bathsheba Dec 06 '16 at 13:34
  • You are accessing your array out of bounds..... How can't be that UB??? – LPs Dec 06 '16 at 13:35
  • Yes,I think izlin is correct if I run loop from 5-8 instead of 0-3 output is 5 6 7 5 6 7 5 6 7.Its not undefined behaviour.I think clang does it differently. – satishdd Dec 06 '16 at 13:47
  • 1
    I would say it is unspecified or implementation-defined behaviour because only the values are not defined but br[-1] is! – izlin Dec 06 '16 at 13:54
  • 1
    @izlin: How do you know br[-1] is defined? If you are thinking in terms of a "stack" then note that a stack is an implementation concept not a language concept. – Bathsheba Dec 06 '16 at 14:03

2 Answers2

3

The behaviour of br[-1] is undefined.

The C standard does not define the behaviour of attempting to access an element outside the bounds of an array. (Interestingly, it's chiefly for this reason why C is regarded as an "unsafe" language by many folk.) You can always inspect the generated assembler for a full analysis of what the compiler has produced.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
1

Here is an example of using negative array idexes.

If you use br[-1] you print the element before your array:

some stuff | your array | more stuff
 X X X X X | 0 0 0 0 ...| X X X X
         ^ this element will be printed

So in one case you maybe got the value of i or j, but the number before your array can change with different compilers or compiler options.

@Bathsheba In my link the top answer says that the behaviour is defined in C99 §6.5.2.1/2, but you don't know which variable is located in front of your array.

The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2))).

Community
  • 1
  • 1
izlin
  • 2,129
  • 24
  • 30