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.
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
int x;
is not initialized but int x[10];
is zero-initialized? That doesn't seem right, is there another clause you left out? –
Rationale new
? ::new( (void*)&a ) A;
and a.i
is no longer initialized. –
Cesta The standard doesn't talk about existence of objects, however, there is a concept of lifetimes of objects.
Specifically, from [basic.life]†
The lifetime of an object of type
T
begins when:
storage with the proper alignment and size for type
T
is obtained, andif the object has non-vacuous initialization, its initialization is complete
With non-vacuous initialization defined as
An object is said to have non-vacuous initialization if it is of a class or aggregate type and it or one of its subobjects is initialized by a constructor other than a trivial default constructor.
We can conclude that for objects with vacuous initializations (such as int
s), their lifetimes begins as soon as their storage is acquired, even if they are left uninitialized.
void foo()
{
int i; // i's lifetime begins after this line, but i is uninitialized
// ...
}
† Links are added for ease of reading, they don't appear in the standard
Use byte array:
alignas(alignof(Mat4)) uint8_t result[sizeof(Mat4)];
// ..
node->updateMatrix( ..., /*result*/ reinterprect_cast<Mat4*>(&result[0]));
The constructors of Mat4
will not trigger.
© 2022 - 2024 — McMap. All rights reserved.
int
for instance. – Syllepsisint n;
. So it is initialized but it isn't initialized. – Ambrosialint
inside aclass
and it will stay uninitialized unless you initialize it. – DecorateObject* obj;
would be uninitialized until you also doobj = new Object();
– Andelfoo f = f;
– BaudelaireObject* obj;
would be initialized (to nullptr) if it is declared in the global scope. – AmbrosialmeaningOfLife
isn't initialized, it doesn't exist in your program – Marsiellaint i;
,i
is default-initialized. But the definition of default-initialization for anint
is "no initialization is performed". In colloquial terms, we just call it not initialized. – Marsiellaint
doesn't initialize it, so it stays uninitializes. – Decorateint
is aprimitive type
.. How can it possibly be an object? An object is structured afaik. I don't know why the standard says that. It's clearly wrong. – Lunnetamemcpy
to work on are objects. – Decorateint
is inherited from C and it isn't defined as Object-Oriented.. Type ofint
should be the exact same across both languages. We're making excuses for bad definitions and wording imo.. but I guess I can't argue the standard. It just doesn't fit any definition ofObject
that I know of. – Lunneta