views:

821

answers:

7

I want to know why exactly static variables in C, C++ and Java are initialized by zero by default? And why this is not true for local variables?

+3  A: 

Paragraph 8.5.6 of the C++ standard states that:

"Every object of static storage duration shall be zero-initialized at program startup"

(The standard also says that the initialization of local variables is undefined)

As to why, the standard doesn't say ;) One guess is that it's reasonably easy to implement without any additional downsides.

Andreas Brinck
He probably wants to know why this choice was made.
GMan
Yes thats true, but my question is why?
Sachin Chourasiya
And the flip side is that default initialization of locals would result in a performance hit. And the C++ designers are more focused on performance than ease of writing correct programs.
Stephen C
Stephen C, not so much performance as control over performance. And not only performance. That actually eases writing correct programs in the long run ;-)
Michael Krelin - hacker
+1  A: 

Speaking for java:

local variables must be initialized before you can access it, because it's a safety gain. The compiler checks for you, if the variable is definitly set.

static or class variables (with an Object type) are initialized with null, because the compiler can't check if they are initialized at compile time. Instead of letting the program fail if it accesses a non-initialized variable, it will be initialized implicit with null.

Variables with a native type can't get a null value, so non-local variables are initialized with 0 or false, as a fallback. It's not best solution, sure, but I don't know a better one. ;-)

Hardcoded
Actually, from the JVM point of view, the local variable simply doesn't exist until it is initialized.
Buhb
The compiler checks that final fields are assigned and not obviously used before assigned. However, there are still ways of seeing the fields before assignments (not true with locals). Non-final static fields should be exceedingly rare (*should*). It leaves open why it is not considered a probably error to leave a field with the default value.
Tom Hawtin - tackline
@Tom - The answer to your "open" question is that it would be exceedingly difficult to come up with JLS rules for this that 1) don't require analysis of all classes in a program, and 2) cope with dynamic loading.
Stephen C
A: 

This is just a guess, but it might be the way it is for statics since it's easy to implement, and useful.

The compiler can co-allocate all the variables into one contigous memory area, and then either emit code (a single memset() call) to clear it before main() is called. In many cases it can also rely on features of the operating system's executable file format, if that format supports "bss sections", which are cleared by the loader instead. This saves space in the executable, you could have

static unsigned char megabyte[1 << 20];

and the executable would not grow by a megabyte.

For local variables, none of these apply; they are allocated "on the fly" (typically on a stack) and it would be a waste of resources to clear them, since they're typically going to be assigned to very soon anyway.

unwind
+1  A: 

I have no idea about java and I doubt it's different for statics/locals in java.

As for c and c++, it's about programmers caring about their code effect and loving being in control. Initializing local variables would imply execution of extra code each time program enters the scope. For frequently called functions that may be a disaster.

Michael Krelin - hacker
Well written ,but thats not an answer to my question
Sachin Chourasiya
Not sure what you want. If you reject this, I'd expect you to accept Andreas' answer. He cites standard and I give you the reason behind it. What answer are you looking for?
Michael Krelin - hacker
This assume that compilers are really dumb. In almost all cases it is easy to see whether a variable is assigned before use.
Tom Hawtin - tackline
What does it have to do with the assumption you accuse me of?
Michael Krelin - hacker
@hacker, I want to know why exactly static variables are initialized by zero?
Sachin Chourasiya
Ah, Sachin, I thought you're asking about why the difference. So is your question why are they initialized or why zero? It is often convenient. For the same reason calloc does it, but malloc exists.
Michael Krelin - hacker
My question is why zero ?
Sachin Chourasiya
Heh, Sachin, I like the question, but I don't think there's a bulletproof answer. I'd say that zero bytes would provide you with the same zero value for all fundamental types.
Michael Krelin - hacker
+1  A: 

So to some extent these are just design decisions on the part of the language designers. But the probable reasons for these decisions in Java are:

  • for static/member variables, if you're going to initialise them to something, then zero is a convenient value because (a) it's generally a suitable value to mean "not set to anything else special", and is the value you would have picked anyway in some cases such as counters; and (b) internally, it's likely that zero can be used for "special" values, notably to represent null in the case of an object reference.
  • for local variables, giving them no default allows for the rule that forces the programmer to set some value before the variable is read, which can actually be useful in allowing the compiler to spot certain errors.

In the case of local variables, it's also conceivable that a local variable could be declared (which at the bytecode/machine code level essentially means allocating stack space/moving the stack pointer) but then never actually written/read in a particular code path. So not having a default avoids doing unnecessary work of setting a default in those cases.

I repeat, though, these are design decisions to some extent. They're essentially a tradeoff between what's likely to be convenient for JVM implementations and convenient for programmers.

N.B. In C/C++, "static" variables mean a different thing to static variables in Java!

Neil Coffey
+7  A: 

Why the static variables are deterministically initialized and local variables aren't?

See how the static variables are implemented. The memory for them is allocated at link time, and the initial value for them is also provided at link time. There is no runtime overhead.

On the other hand, the memory for local variables is allocated at run time. The stack has to grow. You don't know what was there before. If you want, you can clear that memory (zero it), but that would incur a runtime overhead. The C++ philosophy is "you don't pay for things you don't use", so it doesn't zero that memory by default.

OK, but why are static variables initialized to zero, and not some other value?

Well, you generally want to do something with that variable. But then how do you know if it has been initialized? You could create a static boolean variable. But then it also has to be reliably initialized to something (preferably false). How about a pointer? You'd rather want it initialized to NULL than some random garbage. How about a struct/record? It has some other data members inside. It makes sense to initialize all of them to their default values. But for simplicity, if you use the "initialize to 0" strategy, you don't have to inspect the individual members and check their types. You can just initialize the entire memory area to 0.

This is not really a technical requirement. The semantics of initialization could still be considered sane if the default value is something other than 0, but still deterministic. But then, what should that value be? You can quite easily explain why 0 is used (although indeed it sounds slightly arbitrary), but explaining -1 or 1024 seems to be even harder (especially that the variable may not be large enough to hold that value, etc).

And you can always initialize the variable explicitly.

And you always have paragraph 8.5.6 of the C++ standard which says "Every object of static storage duration shall be zero-initialized at program startup".

For more info, please refer to these other questions:

phjr
yes I agreed that the memory of static variables is alllocated at link time, but why it is zero by default.
Sachin Chourasiya
I expanded my answer, hopefully it has the info you're interested in.
phjr
+1  A: 

This has to do with the concept of "only pay for what you use" in C/C++.

For static variables, an initialization can be made without generating code. The object file contains the initial values for the variables in the data segment and when the OS loads the executable it loads and maps this data segment before the program starts executing.

For local variables there's no way to initialize them without code because they are not initialized once, they should be initialized every time you enter their scope; also they are allocated in the stack, and when the allocation occurs the initial value in the stack in the general case is simply what was there before (except those rare moments you grow the stack more than it has grown before).

So to implicitly initialize a local variable the compiler would need to generate code without the programmer explicitly commanding it to do so, which is quite against that "philosophy".

About Java, as far as I know, variables are always initialized when the program enters their scope, no matter if they are static or not. The only significant difference between them is that the scope of static variables is the entire program. Given that, the behavior is consistent among all of them.

Fabio Ceconello