Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do uninitialized objects exist in C++?

If all objects have at least one constructor be it default c'tor defined by the compiler or user defined then how can objects be uninitialized.

like image 635
rimalroshan Avatar asked Sep 26 '17 13:09

rimalroshan


1 Answers

It is possible to declare objects on which no initializations are performed. These objects do exist, they have an indeterminate value, and using this value is undefined behavior (there is an exception to this rule for chars).

Such object can be created by default-intialization. This is stated in the c++ standard, (§11.6 Initializers)[dlc.init]:

To default-initialize an object of type T means:

(7.1) — If T is a (possibly cv-qualified) class type (Clause 12), constructors are considered. The applicable constructors are enumerated (16.3.1.3), and the best one for the initializer () is chosen through overload resolution (16.3). The constructor thus selected is called, with an empty argument list, to initialize the object.

(7.2) — If T is an array type, each element is default-initialized.

(7.3) — Otherwise, no initialization is performed.

Nevertheless, static objects are always zero-initialized. So any built-in with dynamic or automatic storage duration may not be initialized, even if it is a suboject;

int i; //zero-initialized

struct A{
  int i;
  };

struct B
  {
  B(){};
   B(int i)
    :i{i}{}
  int i;
  int j;
  };
A a; //a.i is zero-initialized

int main()
  {
   int j;             //not initialized
   int k{};           //zero-initialized
   A b;               //b.i not initialized
   int* p = new int;  //*p not initialized
   A*   q = new A;    //q->i not initialized
   B ab;              //ab.i and ab.j not initialized
   B ab2{1};          //ab.j not initialized
   int xx[10];        //xx's element not initialized.

   int l = i;    //OK l==0;
   int m = j;    //undefined behavior (because j is not initialized)
   int n = b.i;  //undefined behavior 
   int o = *p; //undefined behavior 
   int w = q->i; //undefined behavior 
   int ex = x[0] //undefined behavior
   }

For member initialization [class.base.init] may help:

In a non-delegating constructor, if a given potentially constructed subobject is not designated by a mem- initializer-id (including the case where there is no mem-initializer-list because the constructor has no ctor-initializer), then — if the entity is a non-static data member that has a default member initializer (12.2) and either

(9.1.1) — the constructor’s class is a union (12.3), and no other variant member of that union is designated by a mem-initializer-id or

(9.1.2) — the constructor’s class is not a union, and, if the entity is a member of an anonymous union, no other member of that union is designated by a mem-initializer-id, the entity is initialized from its default member initializer as specified in 11.6;

(9.2) — otherwise, if the entity is an anonymous union or a variant member (12.3.1), no initialization is performed;

(9.3) — otherwise, the entity is default-initialized (11.6)

Members of a trivial anonymous union may also not be initialized.


Also one could ask if an object life-time could begin without any initialization, for exemple by using a reinterpret_cast. The answer is no: reinterpret_cast creating a trivially default-constructible object

like image 131
Oliv Avatar answered Nov 15 '22 00:11

Oliv