Why do I see strange values when I print uninitialized variables?
In the following code, the variable has no initial value and printed this variable.
int var;
cout << var << endl;
output : 2514932
开发者_开发知识库double var;
cout << var << endl;
output : 1.23769e-307
I don't understand these output numbers. Can any one explain this to me?
Put simply, var
is not initialized and reading an uninitialized variable leads to undefined behavior.
So don't do it. The moment you do, your program is no longer guaranteed to do anything you say.
Formally, "reading" a value means performing an lvalue-to-rvalue conversion on it. And §4.1 states "...if the object is uninitialized, a program that necessitates this conversion has undefined behavior."
Pragmatically, that just means the value is garbage (after all, it's easy to see reading an int
, for example, just gets random bits), but we can't conclude this, or you'd be defining undefined behavior.
For a real example, consider:
#include <iostream>
const char* test()
{
bool b; // uninitialized
switch (b) // undefined behavior!
{
case false:
return "false"; // garbage was zero (zero is false)
case true:
return "true"; // garbage was non-zero (non-zero is true)
default:
return "impossible"; // options are exhausted, this must be impossible...
}
}
int main()
{
std::cout << test() << std::endl;
}
Naïvely, one would conclude (via the reasoning in the comments) that this should never print "impossible"
; but with undefined behavior, anything is possible. Compile it with g++ -02
.
When you do:
int var;
You are only declaring an integer named var
. You do not initialize it with a value, so in whatever location var
is, will be garbage data.
int var = 5;
Would declare var and initialize it to 5.
See more: http://en.wikipedia.org/wiki/Uninitialized_variable
What you're getting is whatever data happened to be on the stack in the place the compiler decided that variable should go interpreted as an integer or a double. It will probably be the same each and every time your program runs because programs generally behave deterministically. Though there are also many cases in which it will end up not being the same from run-to-run of your program. If you change your program in the slightest, or have it make decisions based on user input before you get to that code you may or may not get different numbers.
Basically the value of a variable you haven't initialized is unspecified and may be absolutely anything. There is no rhyme or reason to what's there. Using a variable that is uninitialized is (formally speaking) undefined behavior and may result in all manner of strange things.
Doing this is generally bad practice. You want programs that behave in a predictable fashion, and having uninitialized variables is a source of unpredictability. Note that it is most emphatically not a source of randomness, just unpredictability. Most compilers will complain about code like that if you turn on all the warnings.
In C++, when you declare a variable, the compiler assigns a memory address to it. And that's it, no cleanup is done. This is mostly because C++ (and C) where build with performance in mind. C++ doesn't spend time initializing an address unless you tell it explicitly to do so.
And the so called garbage you see is whatever it was left at that address by the last variable that used it.
Other languages will initialize the data for you. In fact, C# won't let you use the variable until you initialize it. Those languages are designed to be safe, in a sense that it won't let you write a code that mistakenly uses an uninitialized address and crash your program or, worse, corrupt your data.
you didn't initialize var
in either case so you get garbage output.
had you done
const int var(5);
it would be initialized with the value 5
When you declare var it gets assigned a location in memory. However, that memory isn't set to anything by default, so you pick up whatever was there before. This will be some garbage value that has no meaning.
In C++ this is true for both member variables and local variables. However, in languages like Java and C# your member variables are automatically initialized to 0 for numberic types, false for booleans and null for references. This isn't done for local variables and (at least in the C# compiler) your build will fail if you attempt to take the value of an un-initialized variable.
精彩评论