0

I found this occurrence to be rather interesting, let me explain:

When I initialized a int array, I started to wonder how c++ handles an index with a no initialized value. When directly using cout, c++ directly outputs the values as 0. However, when inserting a for loop right afterwards, with the same purpose it instead points to the values inside the memory location, and pretends they were not initialized.

To regenerate this error, copy & paste the code below onto a compiler. Run it once without the for loop, and once with the for loop.

I am just interested to find out why this occurs.


#include <iostream>
using namespace std;

int main() {
    int myArray[4];
    myArray[2] = 32;
    cout << "\n Val 1: "<< myArray[0] << "\n Val 2: "<< myArray[1]<< "\n Val 3: "<< myArray[2]<< "\n Val 4: "<< myArray[3]<< "\n Val 5: "<< myArray[4];
    cout <<"\n ----------------------------";
    /*
    for(int i = 0; i < 5; i++){
        cout << "\n Val " << i << ": " << myArray[i];
    }
    */
    return 0;
}
RyanH
  • 45
  • 1
  • 7
  • VC++ Warns you but behaves the same for both cases. – steveg89 Feb 05 '14 at 20:59
  • 3
    Undefined behavior means anything can happen. It can appear to work correctly, it can die a horrible death or it can just make things goofy every once in a while. Getting incorrect results is expected when you execute code containing undefined behavior . – Captain Obvlious Feb 05 '14 at 21:04
  • @CaptainObvlious printing out a default initialized int does not necessarily produce undefined behavior; it does so only if the indeterminate value assigned to the int is a trap representation (see C++11 8.5/11 and C99 3.17.2, I don't believe C++11 4.1/1 applies because these are default initialized, not uninitialized). – bames53 Feb 05 '14 at 21:59

1 Answers1

1

You are likely witnessing the work of a (clever) optimizer:

Without the for loop, you access the array elements with a fixed constant, a constant which the optimizer can easily proove will lead to an uninitialized value, which is also never used again. As such, it can optimize away actually reading the element from the uninitialized memory, because it is perfectly entitled to use some constant instead.

With the for loop, you have a second usage of the values (through the use of a dynamic index), and the optimizer has to ensure that the undefined value you read from the array elements in the first cout is the same as the one that is later read within the loop. Obviously, it does not try to unroll the loop - after that it would know how to optimize the reads away.

In any case, whenever you access an uninitialized value, that value is undefined, it can be anything, including zero (even though you are not yet invoking undefined behavior). Whenever you use such a value for memory access (uninitialized pointer etc.), you have undefined behavior at its worst.

cmaster - reinstate monica
  • 38,891
  • 9
  • 62
  • 106