-2

Why do I get garbage value if I compile the following C code with GCC/Clang? Note, if I just print the value of x in inner scope I get expected result.

#include<stdio.h>
int main()
{
    int x = 5;
    {
        int x = x;
        printf("%d", x);
    }
    return 0;
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
username_4567
  • 4,737
  • 12
  • 56
  • 92

2 Answers2

4

In this declaration

int x = x;

the point of declaration of the identifier x is after the complete definition of the declarator that is x is already visible before the assignment sign = and hides the variable with the same name declared in the outer block scope..

And you have that x that is not initialized is assigned to itself. As result it has an indeterminate value.

You can imagine it the following way

int x;
x = x;

Exactly the same example exists in the C++ Standard (3.3.2 Point of declaration)

1 The point of declaration for a name is immediately after its complete declarator (Clause 8) and before its initializer (if any), except as noted below. [ Example:

int x = 12;
{ int x = x; }

Here the second x is initialized with its own (indeterminate) value. —end example ]

In the C Standard there is written (6.2.1 Scopes of identifiers)

7 Structure, union, and enumeration tags have scope that begins just after the appearance of the tag in a type specifier that declares the tag. Each enumeration constant has scope that begins just after the appearance of its defining enumerator in an enumerator list. Any other identifier has scope that begins just after the completion of its declarator.

Pay attention to the definition of enumerators. The rule for enumerators is different.

This program is well-formed and the enumerator x will be initialized by the variable x declared in the outer scope (while the enumerator y will be initialized by the preceding enumerator x).

#include <iostream>

int main()
{
    const int x = 10;
    {
        enum E { x = x + 1, y = x };
        std::cout << "E::x = " << x << ", E::y = " << y << std::endl;
    }
    std::cout << "x = " << x << std::endl;
}    

The program output is

E::x = 11, E::y = 11
x = 10
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

The declaration int x = 5; is out of the scope of your second block. This means that variable x in the following piece of code

{
    int x = x;
    printf("%d", x);
}

is different from the outside variable x, declared in main. So when you try to access its value in the assignment, it gives a garbage value as it did not exist in this scope before and therefore it is not initialized.

Marievi
  • 4,951
  • 1
  • 16
  • 33