10

Why does this print 32767 (or some other random number)? What is std::cout printing? Why is it not NULL (or 0)?

int main() 
{
    int a;
    std::cout << a;
}
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Joseph Nields
  • 5,527
  • 2
  • 32
  • 48
  • 3
    ***Why is it not NULL (or 0)?*** Because the standard does not say it has to be initialized to 0. – drescherjm May 12 '15 at 01:52
  • 3
    Why do people just enjoy looking into the barrel and pull the trigger and ask "why did I blew my head off? Shouldn't it be unloaded when I picked up the gun"? – user3528438 May 12 '15 at 01:55
  • 8
    Your use of the term "uninstantiated reference" is incorrect. `int a` is not a reference variable, it is a plain old value variable. And although I've never really heard anyone talk about "instantiating" primitive types (people normally only use the word "instantiate" when talking about user-defined classes, i.e. `class` or `struct` types), when you define a value variable (which is what you did with `int a`), then it is certainly instantiated. – bgoldst May 12 '15 at 01:57
  • @user3528438, coming from Java which doesn't even allow pointers (although arrays are kind of close), this is quite a bit different – Joseph Nields May 12 '15 at 01:57
  • @JosephNields, References in Java work pretty similarly to pointers in C++. – chris May 12 '15 at 01:59
  • @user3528438 In Java you *only* have pointers for user defined types except they call them "references". – Galik May 12 '15 at 02:02
  • 1
    Funny, I haven't yet been able to find a dupe of this question for C++, although I am pretty sure someone asked it before. Most Q&A are C-only tagged, like [this one](http://stackoverflow.com/q/1597405/3093378), although in this case the exactly same stuff applies for C++. – vsoftco May 12 '15 at 02:08
  • @bgoldst I took a C++ course once (pre-1998), and the tutor said "instantiate" when he meant "initialize"; maybe that misconception is widespread – M.M May 12 '15 at 02:13
  • @vsoftco http://stackoverflow.com/questions/29901721/variables-have-values-after-declaring-them/29901840#29901840 – user3528438 May 12 '15 at 02:51

4 Answers4

18

That is because variables with automatic storage duration are not automatically initialized to zero in C++. In C++, you don't pay for what you don't need, and automatically initializing a variable takes time (setting to zero a memory location ultimately reduces to machine intruction(s) which are then translated to electrical signals that control the physical bits).

The variable is being reserved a memory location, and it happens that some junk is at that memory location. That junk is being printed out by cout.

As pointed out by @dwcanillas, it is undefined behaviour. Related: What happens to a declared, uninitialized variable in C? Does it have a value?

From the C++ standard (emphasize mine):

8.5 Initializers [dcl.init]

7) To default-initialize an object of type T means:

  • If T is a (possibly cv-qualified) class type (Clause 9), constructors are considered. The applicable constructors are enumerated (13.3.1.3), and the best one for the initializer () is chosen through overload resolution (13.3). The constructor thus selected is called, with an empty argument list, to initialize >> the object.
  • If T is an array type, each element is default-initialized.
  • Otherwise, no initialization is performed.

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 (5.18). [Note: Objects with static or thread storage duration are zero-initialized, see 3.6.2. — end note ] If an indeterminate value is produced by an evaluation, the behavior is undefined except in the following cases:

— If an indeterminate value of unsigned narrow character type (3.9.1) is produced by the evaluation of:

— the second or third operand of a conditional expression (5.16),

— the right operand of a comma expression (5.19),

— the operand of a cast or conversion to an unsigned narrow character type (4.7, 5.2.3, 5.2.9, 5.4), or

— a discarded-value expression (Clause 5)

...

Community
  • 1
  • 1
vsoftco
  • 55,410
  • 12
  • 139
  • 252
  • 1
    C and C++ have somewhat different rules regarding uninitialized variables. In C, an *indeterminate value* can propagate in computations. For example `int x; int y = x - 1;` is legal in C and results in `y` being indeterminate also. However that causes UB in C++. – M.M May 12 '15 at 02:15
  • @MattMcNabb yes I guessed there may be differences, was searching fervently for a dupe. But I ended up finding the standard quotes :) – vsoftco May 12 '15 at 02:25
7

It's undefined behavior. You are printing whatever occupies the memory of a, which in this case happens to be 32767.

dwcanillas
  • 3,562
  • 2
  • 24
  • 33
  • @vsoftco http://stackoverflow.com/questions/11962457/why-is-using-an-uninitialized-variable-undefined-behavior-in-c To be fair that isn't why I thought it was UB though :) – dwcanillas May 12 '15 at 01:54
  • interesting... I'll take a look at the post, thanks! You're right, it is UB, also related http://stackoverflow.com/a/1597426/3093378, +1 – vsoftco May 12 '15 at 01:55
  • Your answer contradicts itself. You first (correctly) state that the program has undefined behaviour, then you describe "what it does" as if it has defined behaviour. – Asteroids With Wings Nov 15 '20 at 17:23
  • @AsteroidsWithWings I disagree. My view (at least in the context of this answer) is that "Undefined Behavior" is "Unpredictable Behavior". I was not implying that his code would always output `32767`. That was just the example he used, and he even said that the behavior wasn't consistent. I was just pointing out the result of the undefined behavior in the context of the question. – dwcanillas Nov 16 '20 at 19:05
  • There is no "result of undefined behaviour". The behaviour is _undefined_. That's literally the point of it. At the very least this is a bit misleading as to what can reasonably be expected in practice. – Asteroids With Wings Nov 16 '20 at 19:17
  • @AsteroidsWithWings You are wrong. Here, this article explains it better than I can in 500 characters: https://www.learncpp.com/cpp-tutorial/uninitialized-variables-and-undefined-behavior/ – dwcanillas Nov 17 '20 at 06:56
  • That article says exactly what I said. No, I am not wrong. – Asteroids With Wings Nov 17 '20 at 14:18
1

The behaviour is covered by C++14 (N3936) [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.

[...] If an indeterminate value is produced by an evaluation, the behavior is undefined except in the following cases:

and your code is not covered by any of the "following cases" which cover a few situations in which unsigned char indeterminate values are allowed to propagate.

Community
  • 1
  • 1
M.M
  • 138,810
  • 21
  • 208
  • 365
0

Because "a" is not global/static. Its an automatic variable for which initialization happens at run time. If it was global, initialization to zero would have happened at compile time. i.e

• static variables are initialized at compile-time, since their address is known and fixed. Initializing them to 0 does not incur a runtime cost.

• automatic variables can have different addresses for different calls and would have to be initialized at runtime each time the function is called, incurring a runtime cost that may not be needed. If you do need that initialization, then request it.