Verursachen triviale Destruktoren Aliasing?

C ++ 11 §3.8.1 erklärt, dass ich für ein Objekt mit einem trivialen Destruktor seine Lebensdauer beenden kann, indem ich es seinem Speicher zuordne. Ich frage mich, ob triviale Destruktoren die Lebensdauer des Objekts verlängern und Aliasing-Probleme verursachen können, indem sie "ein Objekt zerstören", dessen Lebensdauer ich viel früher beendet habe.

Zu Beginn ist etwas, von dem ich weiß, dass es sicher und ohne Alias ​​ist

void* mem = malloc(sizeof(int));
int*  asInt = (int*)mem;
*asInt = 1; // the object '1' is now alive, trivial constructor + assignment
short*  asShort = (short*)mem;
*asShort = 2; // the object '1' ends its life, because I reassigned to its storage
              // the object '2' is now alive, trivial constructor + assignment
free(mem);    // the object '2' ends its life because its storage was released

Nun zu etwas, das nicht so klar ist:

{
    int asInt = 3; // the object '3' is now alive, trivial constructor + assignment
    short* asShort = (short*)&asInt; // just creating a pointer
    *asShort = 4; // the object '3' ends its life, because I reassigned to its storage
                  // the object '4' is now alive, trivial constructor + assignment
    // implicitly, asInt->~int() gets called here, as a trivial destructor
}   // 'the object '4' ends its life, because its storage was released

§6.7.2 besagt, dass Objekte mit automatischer Speicherdauer am Ende des Gültigkeitsbereichs zerstört werden, was darauf hinweist, dass der Destruktor aufgerufen wird.Wenn es ein int zu zerstören gibt,*asShort = 2 ist eine Aliasing-Verletzung, da ich einen Zeiger eines nicht verwandten Typs dereferenziere. Aber wenn die Lebensdauer der ganzen Zahl schon einmal abgelaufen ist*asShort = 2, dann rufe ich einen Int-Destruktor auf.

Ich sehe verschiedene konkurrierende Abschnitte dazu:

§3.8.8 liest

Wenn ein Programm die Lebensdauer eines Objekts vom Typ T mit statischer (3.7.1), Thread (3.7.2) oder automatischer (3.7.3) Speicherdauer beendet und wenn T einen nicht trivialen Destruktor hat, 39 muss das Programm sicherstellen, dass ein Objekt des ursprünglichen Typs denselben Speicherort belegt, wenn der implizite Destruktoraufruf stattfindet; ansonsten ist das Verhalten des Programms undefiniert.

Die Tatsache, dass sie die Typen T mit nicht-trivialem Destruktor als undefiniertes Verhalten bezeichnen, scheint mir darauf hinzudeuten, dass sich an diesem Speicherort ein anderer Typ mit einem trivialen Destruktor befindetist definiert, aber ich konnte nirgendwo in der Spezifikation finden, die das definiert.

Eine solche Definition wäre einfach, wenn ein Trivial-Destruktor als Noop definiert würde, aber es gibt bemerkenswert wenig in der Spezifikation über sie.

§6.7.3 gibt an, dass Goto in und aus Gültigkeitsbereichen springen darf, deren Variablen Trivialkonstruktoren und Trivialdestruktoren haben. Dies scheint auf ein Muster hinzudeuten, bei dem Trivial-Destruktoren übersprungen werden dürfen, aber der frühere Abschnitt der Spezifikation zum Zerstören von Objekten am Ende des Geltungsbereichs erwähnt nichts davon.

Schließlich gibt es die freche Lesung:

§3.8.1 gibt an, dass ich die Lebensdauer eines Objekts jederzeit starten darf, wenn sein Konstruktor trivial ist. Dies scheint darauf hinzudeuten, dass ich so etwas tun könnte

{
    int asInt = 3;
    short* asShort = (short*)&asInt;
    *asShort = 4; // the object '4' is now alive, trivial constructor + assignment
    // I declare that an object in the storage of &asInt of type int is
    // created with an undefined value.  Doing so reuses the space of
    // the object '4', ending its life.

    // implicitly, asInt->~int() gets called here, as a trivial destructor
}

Die einzige dieser Lesarten, die auf Aliasing-Probleme hinzuweisen scheint, ist §6.7.2 für sich. Wenn der Trivial Destructor als Teil einer ganzen Spezifikation gelesen wird, sollte er das Programm in keiner Weise beeinflussen (allerdings aus verschiedenen Gründen). Weiß jemand, was in dieser Situation passiert?

Antworten auf die Frage(2)

Ihre Antwort auf die Frage