15

I have difficulty in understanding the following paragraph quoted from cppreference about trivial default constructor. I have searched stackoverflow but still didn't get a clear answer. So please help.

A trivial default constructor is a constructor that performs no action. All data types compatible with the C language (POD types) are trivially default-constructible. Unlike in C, however, objects with trivial default constructors cannot be created by simply reinterpreting suitably aligned storage, such as memory allocated with std::malloc: placement-new is required to formally introduce a new object and avoid potential undefined behavior.

Specifically, if the trivial default constructor does nothing, why cannot we reinterpret the storage and pretend there is an object with the given type? Could you please provide some examples for the potential undefined behavior that this would cause?

Max Langhof
  • 23,383
  • 5
  • 39
  • 72
doraemon
  • 2,296
  • 1
  • 17
  • 36
  • The most important job of a compiler is not to compile source code but to reject possibly invalid code. It cannot do this when you use malloc(). – Hans Passant Nov 26 '19 at 15:34
  • 6
    The reasonnis very simple. The less opportunities there are for the programmer to do crazy things, the more opportunities there are for the compiler to do crazy things (agressive optimisations). – n. m. could be an AI Nov 26 '19 at 15:36
  • 1
    For similar reasons that you can't just `*reinterpret_cast(&someNonFloatObject) = 0.1f;`. C++ has a concept of objects and object lifetimes, specified on the abstract machine, and just because there is no CPU instruction to create an object from storage doesn't mean that there is no difference on the abstract machine. – Max Langhof Nov 26 '19 at 15:37
  • 1
    @HansPassant A compiler that rejects all code rejects all invalid code. Anyway, it is not copiler's job to reject programs that have UB. – n. m. could be an AI Nov 26 '19 at 15:39
  • @MaxLanghof A concept of lifetime so well specified, you can refer to objects not yet created. Give me a break. – curiousguy Nov 26 '19 at 15:42
  • 1
    https://stackoverflow.com/q/52154744 – StoryTeller - Unslander Monica Nov 26 '19 at 15:45
  • Possible duplicate of [reinterpret\_cast creating a trivially default-constructible object](https://stackoverflow.com/questions/40873520/reinterpret-cast-creating-a-trivially-default-constructible-object) – Language Lawyer Nov 27 '19 at 12:10

2 Answers2

9

P0593R5 "Implicit creation of objects for low-level object manipulation" gives this example:

struct X { int a, b; };
X *make_x() {
  X *p = (X*)malloc(sizeof(struct X));
  p->a = 1;
  p->b = 2;
  return p;
}

and explains:

When compiled with a C++ compiler, this code has undefined behavior, because p->a attempts to write to an int subobject of an X object, and this program never created either an X object nor an int subobject.

Per [intro.object]p1 (C++17 Draft N4659),

An object is created by a definition, by a new-expression, when implicitly changing the active member of a union, or when a temporary object is created.

... and this program did none of these things.

In practice this works and the UB situation is considered more as a defect in the standard than anything else. The whole objective of the paper is to propose a way to fix that issue and similar cases without breaking other things.

m7913d
  • 10,244
  • 7
  • 28
  • 56
AProgrammer
  • 51,233
  • 8
  • 91
  • 143
0

For "purity" reason.

The alternative and the actual status quo was that every region of storage would contain all objects fitting in that storage, at the same time. Some committee members are uneasy with the status quo and a lot of people feared the notion of having infinitely many objects at the same place (in a virtual, uninitialized state).

Nobody has ever been able to show a logic issue with having infinitely many objects in a region of storage.

Because they had different sections of the standard saying contradicting things, committee members just decided to take seriously one of the worst part of the standard.

Also, using string literals is strictly not allowed, if you really take seriously that one part of the standard.

curiousguy
  • 8,038
  • 2
  • 40
  • 58
  • _using string literals is strictly not allowed_ In deed. There is similar CWG issue about `type_info` objects. Have you reported 'bout string literals? – Language Lawyer Nov 27 '19 at 14:40