Wird in diesem Szenario std::launder benötigt?C++

Programme in C++. Entwicklerforum
Anonymous
 Wird in diesem Szenario std::launder benötigt?

Post by Anonymous »

Ich versuche gerade, eine Slot-Map zu implementieren und habe ein paar Probleme mit der Speicherverwaltung, wenn ich ein std::array habe, wobei Storage die folgende Struktur ist:

Code: Select all

struct Storage final
{
alignas(T) std::byte data[sizeof(T)];
};
wird so etwas benötigt, wenn auf Elemente zugegriffen wird?:

Code: Select all

[[nodiscard]] constexpr auto element_ptr(std::size_t idx) noexcept -> T*
{
return std::launder(reinterpret_cast(std::addressof(m_RawData[idx].data)));
}

[[nodiscard]] constexpr auto element_ptr(std::size_t idx) const noexcept -> T const*
{
return std::launder(reinterpret_cast(std::addressof(m_RawData[idx].data)));
}
In der CPP-Referenz wird nichts über std::launder gesagt, wenn es um die Wiederverwendung von Speicher geht:
https://en.cppreference.com/w/cpp/sprache/lifetime.html

Als Sonderfall können Objekte in Arrays mit unsigned char oder std::byte(seit C++17) erstellt werden (in diesem Fall ist es wird gesagt, dass das Array Speicher für das Objekt bereitstellt), wenn
die Lebensdauer des Arrays begonnen und nicht beendet wurde

der Speicher für das neue Objekt vollständig in das Array passt

es gibt kein Array-Objekt, das diese Einschränkungen erfüllt, das im Array verschachtelt ist.
Wenn dieser Teil des Arrays zuvor Speicher für ein anderes Objekt bereitgestellt hat, endet die Lebensdauer dieses Objekts, weil sein Speicher wiederverwendet wurde, die Lebensdauer des Arrays selbst jedoch nicht Ende (sein Speicher gilt nicht als wiederverwendet).

aber wenn man über std::launder liest, wird Folgendes angegeben:

Code: Select all

std::launder
hat keinen Einfluss auf sein Argument. Für den Zugriff auf das Objekt muss sein Rückgabewert verwendet werden. Daher ist es immer ein Fehler, den Rückgabewert zu verwerfen.
Typische Verwendungen von std::launder umfassen:
  • Erhalten eines Zeigers auf ein Objekt, das im Speicher eines vorhandenen Objekts desselben Typs erstellt wurde, wobei Zeiger auf das alte Objekt nicht wiederverwendet werden können (z. B. weil eines der Objekte ein Unterobjekt der Basisklasse ist);
  • Erhalten eines Zeigers auf ein Objekt, das durch Platzierung von new von einem Zeiger auf ein Objekt erstellt wurde, das Speicher für dieses Objekt bereitstellt.
Die Reachability-Einschränkung stellt sicher, dass std::launder nicht für den Zugriff auf Bytes verwendet werden kann, auf die über den ursprünglichen Zeiger nicht zugegriffen werden kann, wodurch die Escape-Analyse des Compilers beeinträchtigt wird.

Verstehe ich es richtig, dass es vom T abhängt, das im Speicher gespeichert ist, und aus Sicherheitsgründen sollte eine allgemeine Datenstruktur, die Rohspeicher bereitstellt, die Zeiger jedes Mal waschen, wenn auf die Elemente zugegriffen wird?
Unterfrage 1) Kann mir jemand erklären, was damit gemeint ist?

Es gibt kein Array-Objekt, das diese im Array verschachtelten Einschränkungen erfüllt.

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post