0

I have the following C++ code:

#include <iostream>
using namespace std;
#include <stdio.h>


int main (int argc , char ** argv) 
{
    int i1;
    int i2;
    double d1;
    double d2;
    printf("i1: %d, i2: %d, d1: %f, d2: %f \n", i1, i2, d1, d2);
}

The output is

i1: 4195872, i2: 0, d1: 0.000000, d2: 0.000000

Everytime I run the programme I'm getting the same output. Now let's say I'm using the following code:

#include <iostream>
using namespace std;
#include <stdio.h>


int main (int argc , char ** argv) 
{
    int i1;
    int i2;
    double d1;
    double d2;
    cout << "i1: " << i1;
    cout << " i2: " << i2;
    cout << " d1: " << d1;
    cout << " d2: " << d2;
}

Now I'm getting the following output:

i1: 4196144 i2: 0 d1: 6.95294e-310 d2: 0

The value for d1 changes slightly when I rerun the programme, the other values stay the same.

Why are the values initialized this way? Why is there no random initialization or initialization to zero?

machinery
  • 5,972
  • 12
  • 67
  • 118

3 Answers3

2

Your program has Undefined Behaviour, which means the outputs you're getting are completely random (as is the fact that you're getting outputs at all).

In C++, local variables of non-class types are not initialised automatically. Reading the value of an uninitialised variable is undefined.

Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
  • Ok, but if I run the programm 1000 times I'm getting always the same outputs... this is not really random... why is this the case? – machinery Mar 21 '17 at 14:47
  • 1
    @machinery It may happen to be constistent with your current OS version, compiler version, standard library version, compilation flags, and phase of the Moon. If you change any of these, it can start giving different results. **Undefined Behaviour is undefined**, and it cannot be relied upon for anything. – Angew is no longer proud of SO Mar 21 '17 at 14:49
2

Why are the values initialized this way?

Default initialized variables of fundamental types and automatic storage duration have an indeterminate value.

Why is there no random initialization or initialization to zero?

Because the standard doesn't say so, and the compiler implementer chose to not do so. Both randomization and zero initialization are potentially slower than not doing either, so the choice seems logical.

What the standard does say is that reading an indeterminate value has undefined behaviour (except in few select situations, see the standard quote).

current standard draft:

[dcl.init] (12) If no initializer is specified for an object, the object is default-initialized. When storage for an object with automatic or dynamic storage duration is obtained, the object has an indeterminate value, and if no initialization is performed for the object, that object retains an indeterminate value until that value is replaced ([expr.ass]). [ Note: Objects with static or thread storage duration are zero-initialized, see [basic.start.static].  — end note ] If an indeterminate value is produced by an evaluation, the behavior is undefined except in the following cases:

  • (12.1) If an indeterminate value of unsigned narrow character type or std​::​byte type ([cstddef.syn]) is produced by the evaluation of:

    • (12.1.1) the second or third operand of a conditional expression,
    • (12.1.2) the right operand of a comma expression,
    • (12.1.3) the operand of a cast or conversion ([conv.integral], [expr.type.conv], [expr.static.cast], [expr.cast]) to an unsigned narrow character type or std​::​byte type ([cstddef.syn]), or
    • (12.1.4) a discarded-value expression,

    then the result of the operation is an indeterminate value.

  • (12.2) If an indeterminate value of unsigned narrow character type or std​::​byte type is produced by the evaluation of the right operand of a simple assignment operator whose first operand is an lvalue of unsigned narrow character type or std​::​byte type, an indeterminate value replaces the value of the object referred to by the left operand.
  • (12.3) If an indeterminate value of unsigned narrow character type is produced by the evaluation of the initialization expression when initializing an object of unsigned narrow character type, that object is initialized to an indeterminate value.
  • (12.4) If an indeterminate value of unsigned narrow character type or std​::​byte type is produced by the evaluation of the initialization expression when initializing an object of std​::​byte type, that object is initialized to an indeterminate value.
eerorika
  • 232,697
  • 12
  • 197
  • 326
  • It has to be `unsigned char`, right? And only in very limited contexts. – Angew is no longer proud of SO Mar 21 '17 at 13:19
  • "*(unless the type is narrow char).*" - Interesting. I'm just getting to know this! Please help me with the relevant section of the standard... Also, I know a little rationale of the general case as explained [here](http://stackoverflow.com/questions/11962457/why-is-using-an-uninitialized-variable-undefined-behavior-in-c)., But now, I am curious as to why the exception of `unsigned char` – WhiZTiM Mar 21 '17 at 13:33
  • @WhiZTiM standard quoted. Angew's correction is accurate. Reason is probably compatibility with C. I can't imagine a case where you would have any use for an indeterminate value. – eerorika Mar 21 '17 at 13:46
  • So a not initialized variable has undefined behabiour when printing its output. But why is the output the same when I run the programm 1000 times? – machinery Mar 21 '17 at 14:56
  • @machinery Did you expect it to not be same? Why would you expect so? The behaviour is undefined. – eerorika Mar 21 '17 at 14:57
1

It's undefined behavior because uninitialized variables hold the garbage value.

If you don’t initialize an variable that’s defined inside a function, the variable value remain undefined.That means the element takes on whatever value previously resided at that location in memory.

Refer cppreference.

msc
  • 33,420
  • 29
  • 119
  • 214