3

I'm playing with c++ in VisualStudio2010

Please explain why IT happens:

int a, b;
int *p, *q;
cout << a << " " << b;

prints out "0 0". Well it's understandable, uninitialized integer should be 0; but

int a, b;
int *p, *q;
p = &a;
cout << a << " " << b;

output is "1792816880 0"

So if I assign pointer to uninitialized variable it change value from default. Why?

Edit clarification: the question was not about value of uninitialized variable

int a; int *p;
cout << a; // would be 0, because it's loacal variable
p = &a;
cout << a; //not 0;

How getting pointer of a could change it value? when we init variable, we allocate space, some bits, they could be anything, but "p = &a" does it actually change bits in this space?

Viller
  • 540
  • 5
  • 19

7 Answers7

6

Well it's understandable, uninitialized integer should be 0

No.

There is no guarantee of that, it depends on the storage class, If your int is local variable it has a auto storage and it need not be 0.

Accessing Unitialized variables causes Undefined Behavior and Your code is causing an Undefined Behavior. Once there is an Undefined Behavior all bets are off and the behavior cannot be explained.

Regarding Undefined Behavior,

C++ Standard section 1.3.24 states:

Permissible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message).

EDIT:
Given the above that this is Undefined Behavior and One should not write any code which relies on such behaviors, infact One should not even think of writing such code. I find it irrelevant & unproductive to dig in to the implementations of all those compilers to seek an explanation of why it works this way.

If someone finds this reply hardheaded, You are free to downvote. If the downvote count exceeds the upvotes, I would know the answer is unwelcome and I will delete it.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • I don't think the 'undefined behaviour' defence answers the question does it. – trojanfoe Sep 19 '11 at 08:34
  • 2
    @trojanfoe It's the only possible answer. The behavior of the program is undefined, so pretty much anything may happen. – James Kanze Sep 19 '11 at 08:36
  • 3
    It's a cop-out. Can anyone show *why* it does this under both Visual Studio and GNU compilers? – trojanfoe Sep 19 '11 at 08:37
  • @trojanfoe: Edited the Answer to quote the standard. Hope that helps you understand that you cannot warrant explanations for UB's. – Alok Save Sep 19 '11 at 08:42
  • 5
    @Als: C++ is a language, not an implementation. Your "it's undefined behavior, don't do it" approach is fine for questions of the form "X seems to work in C++, should I do it?", but not here. This code *can* be explained, you just need be a bit more pragmatic. I think an appropriate answer would be "Firstly, don't do this. Reading uninitialized variables is UB and you shouldn't rely on UB. That said, here's why two seemingly unrelated things are related..." – GManNickG Sep 19 '11 at 08:46
  • @Als: Thanks for the help! However this does appear to happen on at least 2 completely different platforms and compilers and this behaviour is certainly interesting and I, for one, would like to understand why. Sorry if this cannot be pigeon-holed in the way you would like. – trojanfoe Sep 19 '11 at 08:50
  • 4
    I think the issue is, the behaviour cannot be explained *by the standard*. As GMan says, the behavior of a particular implementation (or a number of implementations) can be explained with reference to implementation details. Someone sufficiently familiar with Visual Studio 2010 (or perhaps just a look at the emitted code) could explain exactly why this is happening. Sometimes you can even predict the garbage value... – Steve Jessop Sep 19 '11 at 08:50
3

This is "undefined behavior" in C++.

When you do not initialize a variable in C++ it is not always zero. That is just by chance. The memory is allocated, and the garbage value which was in that memory location previously will be outputted until it is initialized.

Jan S
  • 1,831
  • 15
  • 21
2

The value of an uninitialized value is not defined. There is no default value. Any value could show up.

Any seemingly unrelated operation you do could change the underlying value of the garbage which the software will give you as an answer to your query of an undefined value.

The bottom line is, do not speculate about what undefined behaviour should happen. It is simply undefined - do not write code with undefined behaviour.

Daniel Daranas
  • 22,454
  • 9
  • 63
  • 116
2

It's undefined behaviour but here is some speculation as to what might be happening:

In the first code sample, the address of the variables is never taken so possibly the compiler has chosen to keep them in registers and they never exist in main memory, and the value of the register happens to be 0.

In the second code sample, the address is taken so the variable has to be in memory (on the stack) so that it can have an address. It just happens that the existing data there was some random garbage.

markh44
  • 5,804
  • 5
  • 28
  • 33
1

You've got a bunch of variables that are not written to, ever. A compiler may decide not to allocate storage for such variables. This may seem harsh, but it's reasonable: modern compilers allocate variable storage on a fine-grained level, and some variables may be unused on some branches. Why bother allocating memory when it's not needed ?

Now, what happens if you read from a "variable" that wasn't allocated memory because you never wrote to it? You'll get some random data, quite possibly another variable. Or a segfault - Undefined Behavior comes in many forms.

Now take your second example: here you do write to one variable, p. Since a didn't need any memory allocation (lacking a write), it may very well alias p. And the value of p, reinterpreted as an int could very well be 1792816880.

MSalters
  • 173,980
  • 10
  • 155
  • 350
0

C++ does not initializes variables on declaration it just allocate RAM memory for them. They can by any value before initialize no metter if you use pointer or not. You should always initialize your variables before use.

EOG
  • 1,677
  • 2
  • 22
  • 36
0

Uninitialized local integers are not guaranteed to be 0 in C++. They are "garbage", hence they can be any value including 0.

Ertan D.
  • 822
  • 1
  • 6
  • 22