4

I was reading Do the parentheses after the type name make a difference with new

There Michael Burr talks about uninitialized and indeterminate values. Want to know the difference between the same.

My understanding is that, uninitialized means, compiler will allocate memory not try to initialize the object. indeterminate-> accessing this object might cause undefined behavior. Please correct me if I am wrong.

Also want to know the difference between default-initialization and value-initialization.

Community
  • 1
  • 1
  • For the last part of your question, there are summaries at http://en.cppreference.com/w/cpp/language/default_initialization and http://en.cppreference.com/w/cpp/language/value_initialization – Cubbi May 23 '14 at 13:57
  • "uninitialized" is a property that appertains to an object: storage has been allocated but no value stored there. "indeterminate" is a property that appertains to a value: it is unspecified which of the set of possible members of the value's type the value has. In some cases the result of performing lvalue-to-rvalue conversion on an uninitialized object (reading the object's stored value) is an indeterminate value, and in other cases doing so results in undefined behavior. – Casey May 23 '14 at 18:25
  • This question is not specific to C++11, if that tag was removed or if C++1y was added I believe I could provide a better answer then what you have now. Do you have a specific reason why you wish to restrict the question to C++11? – Shafik Yaghmour Jun 09 '14 at 12:30

2 Answers2

3

I think your interpretation is close, but not exactly right.

uninitialized means the memory is reserved, but not filled with meaningful data. An easy example:

int* ptr;

All this does is reserve a piece of memory to contain the pointer, but since there is no int yet, the value of that pointer is not altered and contains a random garbage address to a meaningless location.

Another example:

class MyClass
{
    int a;
    int b;

    MyClass() :
        a(b) //Oops
        b(5)
    { }
}

int b is not initialized yet when using it for a and, again, contains random garbage.


An indeterminate state is when the object has been initialized, but (probably because it is not intended to be used anymore) you don't know what's inside it.

Its behaviour is unpredictable, but not invalid (unless, of course, the documentation says it's invalid as well). For instance:

std::string a("text");
std::string b(std::move(a));

string a is now probably just an empty string. Accessing it will not cause undefined behavior, it will behave like any other empty string. Except you don't know for sure that it's empty.

For all you know, it might have replaced its char array with a reference to some static const char array saying "this is an indeterminate object why are you accessing me leave me alone.". Or some complicated series of seemingly random characters that is the result of internal optimizations. You can't know what is in it, and shouldn't use it. But when you do, it won't give you undefined behavior. Just useless behavior, on undefined data.


default-initialization and value-initialization are not part of your main question, you should ask for those in a separate question (assuming you can't find the answer on this site already).

Aberrant
  • 3,423
  • 1
  • 27
  • 38
3

What is Indeterminate value? has a good answer by WhozCraig. There's a discussion in the comments about reading the values. The question is about C99; C++11 standard itself does not define the meaning of "indeterminate value" (not the draft document at least). I'll summarize the some relevant parts parts.

The question itself has the definition of indeterminate value in C99:

3.17.2

1 indeterminate value

either an unspecified value or a trap representation

The linked answer links to another good question about trap representation for further information.

Steve Jessop comments on the effects of reading an indeterminate or an uninitialized value in C or C++.

It's implementation-defined whether or not int has any trap representations. If it doesn't (and I've never actually used an implementation that did have trap values of int), then it is not undefined behavior to read an indeterminate value: you know that it's not a trap value, so it's a valid value of the type int, it's just unspecified which one. In C++, by contrast, it's explicitly UB to read any uninitialized value. In both C and C++ it's UB to read a trap representation

I also found these from The New C Standard(coding-guidelines.com) which comments on the C90, C99 and C++ ('98 and '03) standard.

75:

C++

Objects may have an indeterminate value. However, the standard does not explicitly say anything about the properties of this value.

579:

C90

The C90 Standard specified that reading an uninitialized object was undefined behavior. But, it did not specify undefined behaviors for any other representations.

C++

The C++ Standard does not explicitly specify any such behavior.

Community
  • 1
  • 1
eerorika
  • 232,697
  • 12
  • 197
  • 326