-2

Variable a is declared in two separate functions, but only initialized in one of them. The main function calls the function that declares and initializes a, then it calls the second function which redeclares that variable without initializing it. It prints 42, even though a is initialized in a different function scope whose data should have been destroyed after the function's completion. Why is this happening?

#include <stdio.h>
void foo() {
    int a = 42;
}
void bar() {
    int a;
    printf("%d",a);
}
main() {
    foo();
    bar();
}
too honest for this site
  • 12,050
  • 4
  • 30
  • 52
Y. W.
  • 11
  • 4

4 Answers4

1

The official answer is that this

void bar() {
    int a;
    printf("%d",a);
}

invokes 'Undefined Behavior'. Anyting can happen. It could print a poem, format your hard drive, turn on the lights on white house xmas tree,... It might even print 42 and some people will tell you how that could happen is some cases.

The fact that elsewhere you have another variable called a is irrelevant

pm100
  • 48,078
  • 23
  • 82
  • 145
0

Oooo, that's a good one. Officially it's undefined. But I bet a lot of them would print 42 because the a's likely will use the same memory address on the stack.

So that basics of how this works, is when a function is called the value of the PC (program counter) that the program should return to is pushed on the stack along with the parameters. In this case, both foo and bar have no parameters so just one pointer will be pushed onto the stack (so say a total of 4 bytes starting at relative address 0).

Then when a funciton starts, its variables are pushed onto the stack. In this case, both of them have in a which will be pushed, which is again 4 bytes for each (total of 8 bytes, starting at relative address 4).

This is a common way in C/C++ to grab data from other functions / programs that the function otherwise shouldn't be allowed to access.

TinyTheBrontosaurus
  • 4,010
  • 6
  • 21
  • 34
0

Undefined behaviour. You're printing an uninitialized variable. a in foo is conceptually a different variable to a in bar.

While UB could (According to the standard) do any of all of the bizarre things suggested by @pm100, in the real world it will print out whatever happens to be in some random memory location or register. So, an undefined value.

Will it print 42? Possibly. a: because there's a random chance that the undefined value was 42, b: because possibly the memory/register was written with 42 by foo and hasn't been overwritten by something else.

Can I rely on it always printing 42? 100%, no!

Roddy
  • 66,617
  • 42
  • 165
  • 277
0

Undefined behavior!

Observed behavior is both clang and gcc print 42 if optimization is off. If you add -O1 the foo function effectively vanishes and the printf then prints some garbage.

The following program shows you that the effective address that the a points to is the same in both functions

#include <stdio.h>
#include <stdint.h>
void foo();
void bar();

void foo() {
  uint8_t a = 255;
  uint8_t b = 255;
  printf("%p\n",&a);
}

void bar() {
  uint16_t a;
  printf("%p\n",&a);
  printf("%hu\n",a);
}
int main(void) {
  foo();
  bar();
}

output is

0x7fff54dd259e
0x7fff54dd259e
65535

This is observed behavior on my machine today at this time in these weather conditions. You may of course observe flying pigs, pink elephants or any manner of Heisenbug whilst trying to observe what the above code actually does.

Harry
  • 11,298
  • 1
  • 29
  • 43