Search code examples
cgotovariable-declaration

goto statement in C


#include<stdio.h>

int main() 
{
    int i  = 10;

    printf("0 i %d %p\n",i,&i);
    if (i == 10)
        goto f;

    {
        int i = 20;
        printf("1 i %d\n",i);
    }
    {
        int i = 30;
        f:
        printf("2 i %d %p\n",i,&i); //statement X
    }

    return 0;
}

Output:

[test]$ ./a.out 

0 i 10 0xbfbeaea8

2 i 134513744 0xbfbeaea4

I have difficulty in understanding how statement X works?? As you see the output it is junk. It should rather say i not declared??


Solution

  • That's because goto skips the shadowing variable i's initialization.

    This is one of the minor nuances of the differences between C and C++. In strict C++ go to crossing variable initialization is an error, while in C it's not. GCC also confirms this, when you compile with -std=c11 it allows while with std=c++11 it complains: jump to label 'f' crosses initialization of 'int i'.

    From C99:

    A goto statement shall not jump from outside the scope of an identifier having a variably modified type to inside the scope of that identifier.

    VLAs are of variably modified type. Jumps inside a scope not containing VM types are allowed.

    From C++11 (emphasis mine):

    A program that jumps from a point where a variable with automatic storage duration is not in scope to a point where it is in scope is ill-formed unless the variable has scalar type, class type with a trivial default constructor and a trivial destructor, a cv-qualified version of one of these types, or an array of one of the preceding types and is declared without an initializer.