15

I am confused about the following code:

#include <iostream> int i = 1; int main() { int i = i; std::cout << "i: " << i << "\n"; return 0; } 

Output:

i: 0 

I had expected running the above code would print 1. Can someone please explain the reason for this strange behavior?

8
  • 24
    When strange things happen, it's usually UB. Commented Mar 20, 2016 at 14:10
  • 15
    The warning "main.cpp:13:13: Variable 'i' is uninitialized when used within its own initialization: given by a reasonable compiler may be a hint as to the problem. Perhaps jam up your warning levels and heed their advice. Commented Mar 20, 2016 at 14:11
  • 3
    When you assign int i= i;, i gets initialized with the value of i which you just declared, hence an undefined value. Commented Mar 20, 2016 at 14:20
  • 4
    Please, always compile with -Wall -Werror Commented Mar 20, 2016 at 15:34
  • 2
    aside: just in case you are not familiar with undefined behavior Commented Mar 20, 2016 at 18:32

1 Answer 1

62

You are initializing i with itself. The both i's in int i = i; are the inner one not the outer one. This is undefined behavior and you may get 0 or anything may happen.

This is the right way if you want to assign the outer i to the inner i.

#include <iostream> int i = 1; int main() { int i = ::i; std::cout << "i: " << i << "\n"; return 0; } 

Live Demo


BTW, You should carefully read all the compiler warnings. If you did you could see the problem yourself:

warning 'i' is used uninitialized in this function

Sign up to request clarification or add additional context in comments.

6 Comments

Do you have any snippets from the standard that support the claim that int i = i; is in fact undefined behavior. An uninitialized variable is not undefined behavior it just has an unspecified value. And since this exact construction appears in the standard (3.3.2) with a claim that the value will be indeterminate, I'm highly skeptical that this is UB.
@SteveCox I don't think this is undefined behavior because there is no arithmetic being performed. Using i as the denominator in a division operation may result in undefined behavior depending on various factors.
@johannes, there is a difference between unspecified and undefined behaviour. Unspecified means it has to do something vaguely sensible, but not crash, and definitely no time portals. I think this could be either undefined or unspecified though, so it'd be nice to see where in the standard it says this.
@SteveCox: There's special permission for narrow character types which make the result uninitialized. The example in 3.3.2 uses unsigned char which is a narrow character type. But this code uses int, ergo it requires lvalue->rvalue conversion on an uninitialized value, which causes undefined behavior. See 8.5p12 "If an indeterminate value is produced by an evaluation, the behavior is undefined except in the following cases" (all cases require a narrow character type)
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.