views:

218

answers:

7

In C, automatic variables, if uninitialized, hold a garbage value. However, consider the following program:

int main(){
 signed char term;
 (char)term--;
 printf("%d\n",term);
}

It prints a value of '7'. If I don't do a (char)term--, it prints a value of '8'. So, it definitely doesn't hold a garbage value. Isn't this contradictory?

+13  A: 

That's garbage. You get 8 as garbage, and subtract to get 7.

This is what undefined behavior is. Just because you keep getting 8 doesn't mean it's well-defined. Try doing more complex things in your code. Add variables above and below your char.


About your "test", you say:

However, the consistency is hard to overlook, considering that garbage should be random.

You need to check your assumptions. "garbage should be random" says who? According to what should the garbage be random? The only way garbage will be random is if the system periodically goes through memory and assigns random numbers to it.

When we say "random", we mean we don't know what it will be. That doesn't make it non-deterministic. These are computers. If you tell them to do the same thing over and over, it will do the same thing over and over.

Your compiler and settings keep producing the same code that ends up giving you these garbage values. Deterministic, yet you cannot rely on this behavior: "random".

Also, 1-800 didn't mean for you to take this like you did. "8" does not necessarily denote garbage, as in the way things are set up your compiler fills them with 8. What he means is 8 is just as garbage as any other number.

GMan
+2  A: 

Garbage in terms of the value is whatever was left on the stack by some previous function. Change libc, or any number of things, and that number will change.

+3  A: 

The value 8 is included in the set of numbers which are considered "garbage" or "uninitialised".

1800 INFORMATION
A: 

It does hold garbage, it holds 8 bits of garbage, and reads the binary as a number from 0-255 (Pretending your using an unsigned char).

So the memory could have been like this:

| 0 0 1 0 1 0 1 0 0 1 0 0 1 0 0 1 0 1 0 1 |

And it took the end (1 0 0 1 0 1 0 1) and read it as a number, which is 149. It just depends on what random binary is in the spot of the specified length (ex: unsigned char = 1 byte)

If it was an unsigned int, it would take 4 bytes of random garbage and make it a number.

micmoo
A: 

Think of it as being initialized with an arbitrary value (bit pattern).

That arbitrary value depends on what the stack position for the variable was last used for, it is definitely not a random value. It may or may not be always the same value. It can depend on anything else that happened before.

It is good practice to always initialize automatic variables to avoid undefined behavior.

starblue
+2  A: 

You seem to have gotten the terms "garbage" and "non-deterministic" mixed up. The value in term is considered garbage because you have no control over what value is going to be in it.It can change from platform to platform or run to run, i.e. undefined behavior..

On the other hand, if all things in the program's runtime environment are equal, the value will probably be the same for every run. This doesn't preclude it from being garbage, however.

Falaina
Agree. If you want to understand try single stepping through the code with the debugger, with single step (possibly assembly mode) as this will get you through the startup code which runs before main().
Adriaan
A: 

Thanks for the answers. I tried out a little modification:

int main(){
           signed char term1;
           signed char term2;
           signed char term3;
           printf("%d\n%d\n%d\n",term1,term2,term3);
}

I ran the program on 3 different machines. The result was the same on all 3 machines: term1 gets value = -124, term2 = 4 and term3 = 8. If I remove term3, term1 = 4, term2 = 8. If I remove term2, term1 = 8. So, basically, the last value to be decalred as signed char gets the value of '8'. As 1800 INFORMATION said, '8' is one of the values used to denote garbage, this may be it. However, the consistency is hard to overlook, considering that garbage should be random.

Nothing on a computer is really random. You could use a You might consider trying your program on three different architectures with three different runtimes and different compilers. For example an x86 windows machine, an x86 Linux machine, and a PowerPC Macintosh. My guess is that you'll get different results. You might even get different results with different compilers (e.g., Visual Studio 2008 versus Visual C++ 6.0). The funamental point is that it's inconsistent with respect to the C runtime environment.
Brendan Dowling