Eigenartiger CTor.



  • Habe etwas gefunden wo ich eure Hilfe brauche. Ist so etwas ok?

    struct A{
    //...
    A()
    {
    	memset(this,0,sizeof(A)); // <--- WTF?!
    	Default();
    };
    ///Copy CTor
    A(const A& other)
    {
    	memcpy(this,&other,sizeof(A)); // <--- WTF?!
    };
    
    ~A(){};
    
    A& operator=(const A& other)
    {
    	memcpy(this,&other,sizeof(A));	 // <--- WTF?!
    	return *this;
    };
    // ...
    

    Die Struct sieht sonst wie eine ganz normale Klasse aus, hat Variablen, Funktionen etc..

    Könnte es irgendwo zu Problemen kommen wenn man so etwas verwendet? Habe es zumindest so noch nirgendwo gesehen.


  • Mod

    Das kann in bestimment Situationen funktionieren (wenn alle Member POD sind), aber der Sinn dahinter erschließt sich mir nicht. Erstens sollte das überhaupt keine Vorteile haben, eher im Gegenteil könnte es Compileroptimierungen aktiv verhindern. Und zweitens, wenn ein nicht-POD Member dazu kommt, dann geht das komplett schief. Wenn alle Member POD sind, dann kann man diese Funktionen auch automatisch erzeugen lassen. Der Compiler kann das im Zweifelsfall sogar besser und man braucht auch keinen Funktionsaufruf als möglichen Overhead.

    Spekulation: Der Programmierer hielt sich für den Über-Optimierergott, hat aber überhaupt keine Ahnung. Der leere Destruktor ist auch nicht gerade vertrauenserweckend.



  • Kommt drauf an. Wenn die Struktur nur PODs enthält ist alles in Ordnung, sobald aber komplexe Objekte (solche, die nicht trivial kopiert werden können, z.B. std::string) im Spiel erzeugt der Code UB.



  • sind nur double und int variablen


  • Mod

    blub2 schrieb:

    Habe etwas gefunden wo ich eure Hilfe brauche. Ist so etwas ok?

    Nein. Das führt zu undefiniertem Verhalten.



  • camper schrieb:

    blub2 schrieb:

    Habe etwas gefunden wo ich eure Hilfe brauche. Ist so etwas ok?

    Nein. Das führt zu undefiniertem Verhalten.

    Da war wieder einer schneller als ich. Um genau zu sein führt das laut aktuellem Standard zu UB. Laut C++11 allerdings nicht mehr, da hier die Bedingungen für PODs gelockert wurden. (z.B. Konstruktoren erlaubt.) Das setzt natürlich voraus, dass die Member alle selbst PODs sind.


  • Mod

    314159265358979 schrieb:

    camper schrieb:

    blub2 schrieb:

    Habe etwas gefunden wo ich eure Hilfe brauche. Ist so etwas ok?

    Nein. Das führt zu undefiniertem Verhalten.

    Da war wieder einer schneller als ich. Um genau zu sein führt das laut aktuellem Standard zu UB. Laut C++11 allerdings nicht mehr, da hier die Bedingungen für PODs gelockert wurden. (z.B. Konstruktoren erlaubt.) Das setzt natürlich voraus, dass die Member alle selbst PODs sind.

    Ja und nein. Die Definition von POD hat sich etwas geändert. Obiger Code führt trotzdem zu undefiniertem Verhalten.
    Voraussetzung, damit ein Typ per memcpy kopiert werden darf (und in logischer Erweiterung ggf. memset verwendet werden kann), ist die triviale Kopierbarkeit (3.9/2). Ein selbstdefinierter Copy-ctor ist damit ausgeschlossen (12.8/13).
    Was in C++11 nicht mehr stört, sind andere Konvertierungskonstruktoren und eigene Defaultkonstruktoren, die man z.B. braucht, um skalare Typen zu kapseln.


  • Mod

    camper schrieb:

    Ja und nein. Die Definition von POD hat sich etwas geändert. Obiger Code führt trotzdem zu undefiniertem Verhalten.
    Voraussetzung, damit ein Typ per memcpy kopiert werden darf (und in logischer Erweiterung ggf. memset verwendet werden kann), ist die triviale Kopierbarkeit (3.9/2). Ein selbstdefinierter Copy-ctor ist damit ausgeschlossen (12.8/13).

    Und so schließt sich der Kreis: Wäre der Copy-Konstruktor nicht hier, könnte der Compiler intern memcpy benutzen zum Kopieren und alles wäre ok. Nun benutzt der Copy-Konstruktor selber memcpy und die Aktion wird eben dadurch selbst undefiniert. Wunderschön. 🕶



  • Ist aber auch ganz schön wirr beschrieben im Standard.

    Bei 9/10 steht:

    A POD struct is a non-union class that is both a trivial class and a standard-layout class, ...

    So weit, so gut. Was uns zu der Definition von "trivial class" (9/6) führt:

    A trivial class is a class that has a trivial default constructor (12.1) and is trivially copyable.

    Was uns zu "trivial default constructor" und "trivially copyable" führt:

    A default constructor is trivial if it is not user-provided and if...

    A trivially copyable class is a class that:
    — has no non-trivial copy constructors (12.8),
    — has no non-trivial copy assignment operators (13.5.3, 12.8),
    — has a trivial destructor (12.4).
    ...

    Was uns wiederum weiterführt zu:

    A copy/move constructor for class X is trivial if it is not user-provided and if...

    A copy/move constructor for class X is trivial if it is not user-provided and if...

    A destructor is trivial if it is not user-provided and if...

    Also ist nicht nur der Copy-Ctor das Problem, sondern alles andere auch 🤡


  • Mod

    314159265358979 schrieb:

    Also ist nicht nur der Copy-Ctor das Problem, sondern alles andere auch

    Wie schon gesagt, die notwendige Bedingung ist triviale Kopierbarkeit und nicht mehr die Eigenschaft, POD zu sein (3.9/2).


Anmelden zum Antworten