3

Why the output is not 10 or even 5??

void main()
{
    int a=10;
    goto here;
    {
    int a=5;
    here:
        printf("%i",a);
    }
}

output: Garbage Value

Evg
  • 25,259
  • 5
  • 41
  • 83
Spark
  • 219
  • 2
  • 13

1 Answers1

14

Because there are two a variables, the second shadows the first in the print statement. Since you skipped its initialization, the output is garbage.

Note it is a compiler error to skip past initialization in C++, in C you just get the uninitialized value as you have observed.

Also, it is int main(), not void main().

Quimby
  • 17,735
  • 4
  • 35
  • 55
  • In fact it is interesting. One could say that `goto` have skipped the second definition too, as the definition and the initialization are actually the same statement here. – Eugene Sh. Sep 03 '21 at 18:41
  • `void main()` is allowed in C (but not in C++). – Adrian Mole Sep 03 '21 at 18:41
  • 1
    MSVC does issue a warning about this `uninitialized local variable 'a' used`. – Weather Vane Sep 03 '21 at 18:43
  • 1
    @AdrianMole Not in standard C AFAIK. – Quimby Sep 03 '21 at 18:44
  • 1
    The C standard allows (but does not require) that an implementation accept a `main` with a return type other than `int`. – Jerry Coffin Sep 03 '21 at 18:46
  • 1
    Shouldn't it be `main(void)` for C (regardless of the return type)? – Yun Sep 03 '21 at 18:47
  • 1
    @Yun: there's no necessity for the `void` in this case. If your code is at all sane, you'll never call `main` yourself anyway. – Jerry Coffin Sep 03 '21 at 18:49
  • @Quimby: The exact wording from the C standard is: "The function called at program startup is named main. The implementation declares no prototype for this function. It shall be defined with a return type of int and with no parameters [...] or with two parameters [...] **or in some other implementation-defined manner.**" (emphasis added). – Jerry Coffin Sep 03 '21 at 18:52
  • @JerryCoffin It's a language-laywer-type diffierence, sure. But I do believe the standard explicitly mentions "no parameters" (and not "any number of parameters") and `int main(void)`: https://stackoverflow.com/questions/2108192/what-are-the-valid-signatures-for-cs-main-function – Yun Sep 03 '21 at 18:56
  • @EugeneSh. -- `goto` happens at runtime, not compile time; it has no effect on declarations or definitions. – Pete Becker Sep 03 '21 at 19:00
  • @PeteBecker I understand the under-the-hood working, but I wonder what is the formal explanation of the behavior. – Eugene Sh. Sep 03 '21 at 19:01
  • @EugeneSh. -- that's not "under-the-hood working". It's why `goto` doesn't' affect declarations or definitions. That's not its job. – Pete Becker Sep 03 '21 at 19:03
  • @PeteBecker Then why should it affect the initialization? If you make the second declaration `static`, its initialization won't get "skipped". Or it is simply kind of UB. – Eugene Sh. Sep 03 '21 at 19:06
  • @JerryCoffin In C, is the `(void)` parameter spec in a function not accepting parameters really needed when the definition of the function is also the declaration? I was under the impression that you only need `(void)` in prototypes. – Ted Lyngmo Sep 03 '21 at 19:12
  • @JerryCoffin Apologies, I see the difference now. This basically means that _any_ main declaration is "valid C", although I think this "implementation-defined" option was given to accommodate specific compilers for, e.g., embedded systems. – Yun Sep 03 '21 at 19:13
  • 1
    @Yun: Yes, it's left wide open, but not (at least primarily) for embedded systems--this is in the section on "hosted environment". There's another section on "free standing environment" (which is for embedded), it's completely wide open: "In a freestanding environment (in which C program execution may take place without any benefit of an operating system), the name and type of the function called at program startup are implementation-defined." – Jerry Coffin Sep 03 '21 at 19:22
  • @EugeneSh. -- there's nothing special about the initialization; it's just code, and the `goto` skips the code between the goto statement and its target. If there was an output statement instead of the initialization the output statement wouldn't get executed either. – Pete Becker Sep 03 '21 at 19:22
  • 1
    @TedLyngmo: A new-style (not really new any more) function definition normally acts as prototype, but if the parens are empty, that makes it an old-style function definition (that is, the identifier-list for an old-style declaration is optional, but a parameter-type-list isn't optional, and has to contain at least one parameter-declaration. – Jerry Coffin Sep 03 '21 at 19:30