tags:

views:

206

answers:

6
int main()
{
  int x=5,y=10,z=15;
  printf("%d %d %d");
  return 0;
}

Output: 15 10 5 //In Turbo C 4.5

    3 Garbage values in gcc compiler

My teacher told me when we define the variables like int x=5,y=10,z=15; they are by default taken as auto type and stored in stack.When you try print 3 integer values without using their names by printf(), it will print those 3 values in LIFO format as Turbo C compiler does. But what I think when we define 3 integer variables, they may not be stored in continuous memory locations.So when I try to print 3 integer values without using their names, the compiler will print any three values from top of the stack.so the output will come 3 garbage values as in gcc..

+4  A: 

This is undefined behavior.

With an optimizing compiler, these 3 values might be optimized out as they are not used. It will print garbage.

Didier Trosset
A: 

In MingW-GCC: 3 garbage values.

In VC++ 2010: 0, 0, and a garbage value.

Ruel
+2  A: 

If there are insufficient arguments for the format, the behavior is undefined.

jleedev
+9  A: 

This code just shows that Turbo C is poor at optimizing code and puts everything on the stack, while gcc is more aggressive and keeps it in registers or throws it away all together because these three variables have no purpose.

Anyway, calling printf with a pattern that requires three arguments without providing these arguments, is a mistake.

Update:

As an explanation: I'm assuming that printf() will always take its argument from the stack since it's a function with a variable argument list. Or does anybody know any other calling convention for functions like printf()? Futhermore, I'm assuming there's no need to put anything else on the stack as there are no other variables. So this mistaken call of printf will print whatever is on top of the stack in main(). But there might be other architectures and calling conventions where my assumpations don't hold.

Codo
Given that printf is a library function I fail to see how the compiler is able to choose which way to pass parameters to it. A calling convention was chosen when the library was compiled and the compiler must conform.
torak
The optimization is not in the call of _printf()_ but rather in how the local variables in _main()_ are stored. The problemtic call of _printf()_ just reveals what's on the stack.
Codo
+3  A: 

The behavior is undefined, meaning the compiler is free to handle the situation in any way it sees fit. As far as the language standard is concerned, both Turbo C and gcc are doing the "right" thing.

John Bode
And the programmer who wrote the code is not 'doing the "right" thing'!
Jonathan Leffler
+1  A: 

Your teacher is wrong, but not entirely.

Variables declared within a function are by default auto rather than static.

int foo(void) {
    static int x;
    int y;
    auto int z;

    /* ...other code... */
}

This means that in the function above y is auto, just like z, even though the auto keyword is not used in its declaration. The auto keyword is almost never used, by the way. Many C (and C derivative language) programmers don't even know that auto is a keyword because it is used so infrequently.

Being an auto variable usually means that the variable is stored on the program's system stack or in registers or some mix of these. It can be at different places at different times during the course of execution of the function, and local variables that are in registers are often pushed to the stack when another function is called. Some local variables may even be optimized away, meaning that at some point the compiler was able to determine that a particular variable's future value was no longer needed to satisfy the input needs of the future code (or the variable doesn't change and its value is just encoded within instructions). This complicates using debuggers on optimized code.

When you take the address of a local variable the compiler then tries to lock it down to a specific address (probably by storing it on the stack).

When most compilers look at your code they will see that the names of those local variables are not used after their declaration and may decide to just not store their values anywhere. Even if it does store those values on the stack it may also push other values on the stack before setting up to call printf. Just as the compiler does not have to keep the variables you named around it is also free to create it's own temporary variables.

nategoose