1

In C++ Primer Plus (6th. edition), page 73, it states:

If you don't initialize a variable that is defined inside a function, the variable's value is indeterminate. That means the value of whatever happened to be sitting at that memory location prior to the creation of that variable.

Does that mean I can use an uninitialized variable to get data on the memory location at that point in the program? If true, are there any instances where this property is useful?

dayuloli
  • 16,205
  • 16
  • 71
  • 126
  • 3
    Yes you could, but no, it is never useful. – imreal Jun 21 '14 at 06:30
  • Also see [Is uninitialized local variable the fastest random number generator?](http://stackoverflow.com/questions/31739792/is-uninitialized-local-variable-the-fastest-random-number-generator/31746063#31746063) – Shafik Yaghmour Oct 26 '15 at 01:36

2 Answers2

4

The standard's wording for what you quoted is as follows (§8.5 [dcl.init]):

If no initializer is specified for an object, the object is default-initialized; if no initialization is performed, an object with automatic or dynamic storage duration has indeterminate value.

The book is a little misleading about the previous value being available at that location. It is often true, but not necessarily.

The important point is that accessing the value of such a object results in undefined behaviour. Accessing the value of a object is formally known as lvalue-to-rvalue conversion, which says this (§4.1 [conv.lval]):

If the object to which the glvalue refers is not an object of type T and is not an object of a type derived from T, or if the object is uninitialized, a program that necessitates this conversion has undefined behavior.

This occurs only when an operator in an expression requires an rvalue operand, which is usually the case. However, the unary & operator requires an lvalue operand, so lvalue-to-rvalue conversion is not applied. That means taking the address of an uninitialized variable is fine. This makes logical sense, because the object exists and has a valid address, it just isn't initialized. Taking the address doesn't require accessing the object's value.

Why would you do this? It's hard to think of a specific example because the idea is very broad and because we don't often leave our variables uninitialized (if at all). If you needed to store the address of an object before you assigned a value to it though, this is what you would need to do. You could later access the object through that pointer (once it has been assigned to). In fact, you could assign to it through the pointer.

Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324
  • Thanks for this detailed response. I've just started to learn C++ today. I Googled 'uninitialized variable C++' and everyone just say never do it, it gives bugs...So I was just curious whether someone can exploit this 'bug' and do something with it (like "storing the address of an object") I shall read further into the book and accept an answer once I understand it. Thanks again. – dayuloli Jun 21 '14 at 06:43
  • @dayuloli It's not really exploiting everything. I should probably explain *why* accessing an indeterminate value is undefined behaviour. The C++ standard likes to give compilers as much freedom as possible to avoid doing more work than necessary. If it said "uninitialized variables should be given the value 0", it would mean that the compiler would have to emit an extra instruction for assigning 0 to this object, even though it might be unnecessary. By making it undefined, this means the compiler doesn't have to do anything because it doesn't care about the value. – Joseph Mansfield Jun 21 '14 at 06:49
  • @dayuloli In practice, this means that the object just has the value that was at the same memory location previously, because the compiler doesn't emit any instruction to overwrite this value. The compiler *could* emit an instruction to set it to 0 (or even to 99 if it so pleased), because "undefined behaviour" allows for anything. Undefined behaviour is so broad, however, that the compiler could equally emit an instruction to destroy the universe and that would be valid behaviour. That's why you should always avoid undefined behaviour (unless you are a super villain). – Joseph Mansfield Jun 21 '14 at 06:51
  • Thank you for the further clarification. If I understood correctly, are you saying that the value stored in an uninitialized variables varies by compiler, as well as the memory pointer/location/address-thingy at the time the variable is declared? – dayuloli Jun 21 '14 at 06:54
  • @dayuloli The value of the variable is indeterminate. In practical terms, yes it varies by compiler, machine, etc. In C++ terms, it doesn't make sense to even discuss the value of the variable if it is uninitialized. If you try to access an uninitialized variable in your program, your program has undefined behaviour. As far as C++ is concerned, this means your program can do *ANYTHING*. – Joseph Mansfield Jun 21 '14 at 07:02
  • @dayuloli The "memory pointer/location/address-thingy" is technically the unary `&` operator but also known as the address-of operator. My answer is saying that it is *NOT* undefined behaviour to take the address of an uninitialized variable. It is perfectly fine to take the address of an uninitialized variable. – Joseph Mansfield Jun 21 '14 at 07:04
  • Oh! I see! It is starting to make sense now. I should never use an uninitialized variable because accessing it can make the program do anything, and so it will most likely break and almost always do nothing useful. But the uninitialized variable still has an address, which can be found using the `&` operator, since that is only retrieving the address and do not try to access the value of the uninitialized variable (which is undeterminate). Have I got it right this time? – dayuloli Jun 21 '14 at 07:08
1

While the standard effectively forbids ever using the value of an uninitialized variable, you are usually able to read it anyway, and it will usually indeed contain whatever value was last stored at that location.

However, this information is not useful in any way. Since your program always runs in its own private virtual address space, anything you might read has been written by your own program. I. e., it's information that you have already anyway, and which you can pass around in much more secure ways. This is especially true if you are using an uninitialized variable within a function: all you will ever be able to see that way is information that was written to a local variable by some function that you called earlier.

You might be able to find out some internals of the standard C library and other libraries that you use because their code runs within your address space. But most information will not be stored on the stack anyway, so you would need to read data from some other memory locations than an uninitialized variable. You would need to dereference pointers to stuff that you don't own, and that is really deep down in undefined behaviour. If you try this, you will most likely get segfaults.

So, yes, it's possible, but...

cmaster - reinstate monica
  • 38,891
  • 9
  • 62
  • 106