Frage zu einem Codeausschnitt aus derBoost-Library
-
Hallo,
kann mir jemand erklären, was diese u.g. Zeile ungefähr macht? Für mich sieht der Code ein bisschen komisch aus. Habe ich so bis jetzt noch nicht gesehen.https://github.com/boostorg/system/blob/develop/include/boost/system/detail/error_code.hpp, Zeile 163.
#if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR) error_code( std::error_code const& ec ) BOOST_NOEXCEPT: lc_flags_( 1 ) { ::new(d2_) std::error_code(ec); //Zeile 163 } #endif
d2 ist ein char Array (unsigned char d2_[ sizeof(std::error_code) ];). Das Array ist genauso groß wie die Klasse error_code in Bytes. Aber der new Aufruf ist doch nutzlos ohne einen Zeiger, der die Adresse von new aufnimmt?
Was ist 'std::error_code(ec);'? Sieht mir nach einem Konstruktoraufruf. Aber wieso ist zwischen new und dem Konstrukturaufruf kein Semikolon?
-
@asd1 sagte in Frage zu einem Codeausschnitt aus derBoost-Library:
Aber der new Aufruf ist doch nutzlos ohne einen Zeiger, der die Adresse von new aufnimmt?
Da ist ein placement new, d.h. das Objekt (std::error_code) wird an der Stelle von d2_ konstruiert, und mit ec initialisiert.
-
new (argumentList1) Klassenname(argumentList2)
ist die sog. "placement new" Syntax.Wenn
argumentList1
aus genau einem Zeiger besteht, dann hat das zur Folge dass der Speicher für das Objekt nicht dynamisch angefordert wird, sondern das Objekt an der angegebenen Stelle im Speicher erzeugt wird.Daher muss man den zurückgegebenen Zeiger auch nicht unbedingt wo abspeichern.
-
Ach Du meine Güte... So einem Konstrukt bin ich ja noch nie begegnet. Ich google da mal ein bisschen, damit ich damit spielen kann.
Vielen Dank!
-
In modernen C++ hat sich der Nutzen von placement new noch mehr verringert. Man sollte mittlerweile für Container o.ä. eigentlich Allokatoren nutzen, und dann ruft man nicht mehr placement new direkt auf sondern
std::allocator_traits<Allocator<T>>::construct
und entsprechendstd::allocator_traits<Allocator<T>>::destroy
auf anstatt placement new und den Destruktor.Es bleibt nur noch ein Bereich übrig, in dem man selbst Speicher dynamisch über was anderes als new anfordert und dort C++ Objekte konstruieren will. Allerdings sollte man mittlerweile eher darauf verzichten, und dafür eher
std::vector
nutzen.
-
Das ist auch eine sehr spezielle Sache für sehr spezielle Fälle.
Sollte man nicht verwenden so lange man keinen wirklich guten Grund dafür hat.Ein Problem ist nämlich wie man dann, wenn man den zurückgegebenen Zeiger eben nicht abspeichert, wieder an einen Zeiger auf das Objekt kommt. Wenn ich mich richtig erinnere muss man dazu nämlich in manchen Fällen
std::launder
verwenden.
-
@asd1 sagte in Frage zu einem Codeausschnitt aus derBoost-Library:
Ach Du meine Güte... So einem Konstrukt bin ich ja noch nie begegnet. Ich google da mal ein bisschen, damit ich damit spielen kann.
Vielen Dank!Du brauchst sowas, wenn du besispielsweise eine Union hast. Siehe das zweite Beispiel hier: https://en.cppreference.com/w/cpp/language/union
-
@wob sagte in Frage zu einem Codeausschnitt aus derBoost-Library:
Du brauchst sowas, wenn du besispielsweise eine Union hast. Siehe das zweite Beispiel hier: https://en.cppreference.com/w/cpp/language/union
Der Boost Code nutzt eine Union.
-
@john-0 sagte in Frage zu einem Codeausschnitt aus derBoost-Library:
[...]
Placement
new
ist völlig ok wenn man seinen Dreck auch selber wieder wie es sich gehört wegräumt.