views:

1106

answers:

7

Quick question-- if in C I write:

int num;

Before I assign anything to num, is the value of num indeterminate?

+5  A: 

The value is undefined (or indeterminate to use another English word with the same semantic meaning in this context); it may be whatever was previously in the memory location.

Software Monkey
Thanks, as I suspected. Thanks for the quick reply!
Jasie
Except, it is not the right answer.
DigitalRoss
Indeed. As mentioned in my answer, _static_ uninitialized values are default-initialized to zero. And "whatever was previously in the memory location" is not behavior required by the relevant standards :)
bdonlan
This is a problem with the "right" answer being determined by the person who asked the question (and therefore, has already given a strong indication that s/he doesn't know the right answer with any certainty. In some cases, testing and seeing if it works puts them in a good position to do that, but in others (including this one) it doesn't...
Jerry Coffin
Perhaps there ought to be a cooldown timer for answers - wait at least 5 minutes before accepting an answer, sort of thing? OTOH that might tend to discourage accepting...
bdonlan
I rushed to accept, but since have changed the accepted answer. But since I didn't declare it as static, Software Monkey was right in many of the cases. If someone comes along later and expands the answer, I think it's ambiguous whether or not the accepted answer should be changed.
Jasie
The actual word the standard uses for auto storage class initial value is *indeterminate*.
DigitalRoss
@Jasie: Even if your question was specifically about automatic variables, "whatever was previously in the memory location" is not the right answer.
AndreyT
@Audrey: Perhaps, but "undefined" certainly *is*, since the spec does not define it, which is what indeterminate means in the context.
Software Monkey
A: 

We used to demo a debugger in the past looking at an int a; line. It contained an indeterminate value (large negative number) which seemed to be the same every time. Regardless, do not assume that your int is 0.

Traveling Tech Guy
+19  A: 

Static variables (file scope and function static) are initialized to zero:

int x; // zero
int y = 0; // also zero

void foo() {
    static int x; // also zero
}

Non-static variables (local variables) are indeterminate. Reading them prior to assigning a value results in undefined behavior.

void foo() {
    int x;
    printf("%d", x); // the compiler is free to crash here
}

In practice, they tend to just have some nonsensical value in there initially - some compilers may even put in specific, fixed values to make it obvious when looking in a debugger - but strictly speaking, the compiler is free to do anything from crashing to summoning demons through your nasal passages.

As for why it's undefined behavior instead of simply "undefined/arbitrary value", there are a number of CPU architectures that have additional flag bits in their representation for various types. A modern example would be the Itanium, which has a "Not a Thing" bit in its registers; of course, the C standard drafters were considering some older architectures.

Attempting to work with a value with these flag bits set can result in a CPU exception in an operation that really shouldn't fail (eg, integer addition, or assigning to another variable). And if you go and leave a variable uninitialized, the compiler might pick up some random garbage with these flag bits set - meaning touching that uninitialized variable may be deadly.

bdonlan
oh no they aren't. They might be, in debug mode, when you aren't in front of a customer, on months with an R in, if you're lucky
Martin Beckett
what aren't? the static initialization is required by the standard; see ISO/IEC 9899:1999 6.7.8 #10
bdonlan
first example is fine as far as I can tell. I'm less as to why the compiler might crash in the second one though :)
Stuart
@Stuart: there's a thing called "trap representation", which is basically a bit pattern that does not denote a valid value, and may cause e.g. hardware exceptions at runtime. The only C type for which there's a guarantee that any bit pattern is a valid value is `char`; all others can have trap representations. Alternatively - since accessing uninitialized variable is U.B. anyway - a conforming compiler might simply do some checking and decide to signal the problem.
Pavel Minaev
bdonian is correct. C has always been specified fairly precisely. Prior to C89 and C99, a paper by dmr specified all these things in the early 1970's. Even in the crudest embedded system, it only takes one memset() to do things right, so there is no excuse for a nonconforming environment. I have cited the standard in my answer.
DigitalRoss
+1 for nasal demons.
Chris Lutz
I liked blueberry pancakes...
DigitalRoss
+2  A: 

That depends. If that definition is global (outside any function) then num will be initialized to zero. If it's local (inside a function) then its value is indeterminate. In theory, even attempting to read the value has undefined behavior -- C allows for the possibility of bits that don't contribute to the value, but have to be set in specific ways for you to even get defined results from reading the variable.

Jerry Coffin
A: 

The basic answer is, yes it is undefined.

If you are seeing odd behavior because of this, it may depended on where it is declared. If within a function on the stack then the contents will more than likely be different every time the function gets called. If it is a static or module scope it is undefined but will not change.

simon
A: 

It depends on the storage duration of the variable. A variable with static storage duration is always implicitly initialized with zero.

As for automatic (local) variables, an uninitialized variable has indeterminate value. Indeterminate value, among other things, mean that whatever "value" you might "see" in that variable is not guaranteed to be stable. For example, in practice (i.e. ignoring the UB for a second) this code

int num;
int a = num;
int b = num;

does not guarantee that variables a and b hold identical values. Interestingly, this is not some pedantic theoretical concept, this readily happens in practice as consequence of optimization.

So in general, the popular answer that "it is initialized with whatever garbage was in memory" is not even remotely correct. Uninitialized variable's behavior is different from that of a variable initialized with garbage.

AndreyT
+8  A: 

0 if static or global, indeterminate if storage class is auto

C has always been very specific about the initial values of objects. If global or static, they will be zeroed. If auto, the value is indeterminate.

This was the case in pre-C89 compilers and was so specified by K&R and in DMR's original C report.

This was the case in C89, see section 6.5.7 Initialization.

If an object that has automatic storage duration is not initialized explicitely, its value is indeterminate. If an object that has static storage duration is not initialized explicitely, it is initialized implicitely as if every member that has arithmetic type were assigned 0 and every member that has pointer type were assigned a null pointer constant.

This was the case in C99, see section 6.7.8 Initialization.

If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. If an object that has static storage duration is not initialized explicitly, then:
— if it has pointer type, it is initialized to a null pointer;
— if it has arithmetic type, it is initialized to (positive or unsigned) zero;
— if it is an aggregate, every member is initialized (recursively) according to these rules;
— if it is a union, the first named member is initialized (recursively) according to these rules.

And finally, as to what exactly indeterminate means, I'm not sure for C89, C99 says:

3.17.2
indeterminate value

either an unspecified value or a trap representation

DigitalRoss
indeterminate usually (used to?) means it can do anything. It can be zero, it can be the value that was in there, it can crash the program, it can make the computer produce blueberry pancakes out of the CD slot. you have absolutely no guarantees. It might cause the destruction of the planet. At least as far as the spec goes... anyone who made a compiler that actually did anything like that would be highly frowned upon B-)
Brian Postow