0

The output in the following code is really mysterious.

#include <stdio.h>

void funktion(int x) {}

void test() {
    int foo;
    printf("test = %d\n", foo);
}

int main() {
    test();
    funktion(5);
    test();

    return 0;
}

Why will the foo-var initialised with the value of the parameter of funktion()? I don't understand why foo-var is initialised by the function-parameter. I know that I can fix it with a explicit initialisation - but I want to understand the mystery. Thanks!

  • Undefined behavior is to use an uninitialized variable. – Eugene Sh. Mar 19 '18 at 17:40
  • It is Undefined Behavior to read a value from an uninitialized variable. It can be anything. – Christian Gibbons Mar 19 '18 at 17:40
  • 1
    In C it's not undefined behavior. But the value of uninitialized local variables (like `foo`) is *indeterminate*. – Some programmer dude Mar 19 '18 at 17:41
  • @Someprogrammerdude Is *printing* indeterminate value defined (yeah, I have had this discussion bookmarked somewhere..)? – Eugene Sh. Mar 19 '18 at 17:42
  • 2
    @EugeneSh. I *think* so, but I'm not 100% certain. I think it's only UB if the indeterminate value is a *trap value* (which for integers will be never). – Some programmer dude Mar 19 '18 at 17:43
  • So it's only a coincidence that the value of foo is the parameter of funktion()? I think foo use the free spacecell from the parameter and initialised with the content of this space cell? –  Mar 19 '18 at 17:45
  • @Waldi It's up to the compiler on how to implement it. In your case it might be this way, but it is not something you can rely on. – Eugene Sh. Mar 19 '18 at 17:47
  • Yes, it is possible that the memory segment that was used for the argument to funktion happened to be reused by foo. – Christian Gibbons Mar 19 '18 at 17:48
  • @Someprogrammerdude I hadn't considered that distinction. Makes sense. – Christian Gibbons Mar 19 '18 at 17:50
  • Thanks to all for your help! –  Mar 19 '18 at 17:55
  • 2
    @Someprogrammerdude The only type guaranteed *not* to have a trap representation is ` unsigned char`. Any other type may, depending on the implementation. On systems most people are likely to encounter (i.e. x86 Linux or Windows) there typically aren't any. A signed integer could have a trap representation if, for example, it uses one's compliment representation and does not support negative 0. – dbush Mar 19 '18 at 18:09

1 Answers1

1

I've added comments to your main() function that explains why is it so. By the way, you're in undefined behaviour land, and different platforms might yield different results.

int main() {
    // no return, no parameter, one local variable of type int.
    // This pushes an int on the stack, uninitialized (the local variable).
    test();
    // Stack pointer is back to where it was.

    // no return, one int parameter, no local variables.
    // This pushes an int with value=5 on the stack (the parameter).
    funktion(5);
    // Stack pointer is back to where it was.

    // no return, no parameter, one local variable of type int.
    // This pushes an int on the stack, uninitialized (the local variable). 
    // Previous value of that memory comes from funktion() call.
    test();
    // Stack pointer is back to where it was.

    return 0;
}
Jazzwave06
  • 1,883
  • 1
  • 11
  • 19