C++-Attribut: carries_dependency (seit C++11)(entfernt in C++26)
Von cppreference.com
< cpp | language | attributes
Gibt an, dass sich die Abhängigkeitskette in release-consume std::memory_order in und aus der Funktion fortpflanzt, was es dem Compiler ermöglicht, unnötige Speicherzaun-Instruktionen zu überspringen.
Inhalt |
[bearbeiten] Syntax
[[carries_dependency]]
|
|||||||||
[bearbeiten] Erklärung
Dieses Attribut kann in zwei Situationen auftreten:
1) Es kann auf die Parameterdeklarationen einer Funktion oder Lambda-Ausdrücke angewendet werden, in diesem Fall gibt es an, dass die Initialisierung des Parameters eine Abhängigkeit in die lvalue-zu-rvalue-Konvertierung dieses Objekts trägt.
2) Es kann auf die Funktionsdeklaration als Ganzes angewendet werden, in diesem Fall gibt es an, dass der Rückgabewert eine Abhängigkeit zur Auswertung des Funktionsaufruf-Ausdrucks trägt.
Dieses Attribut muss auf der ersten Deklaration einer Funktion oder einem ihrer Parameter in irgendeiner Übersetzungseinheit erscheinen. Wenn es nicht auf der ersten Deklaration einer Funktion oder einem ihrer Parameter in einer anderen Übersetzungseinheit verwendet wird, ist das Programm schlecht geformt; keine Diagnose erforderlich.
[bearbeiten] Beispiel
Fast unverändert übernommen von SO.
Führen Sie diesen Code aus
#include <atomic> #include <iostream> void print(int* val) { std::cout << *val << std::endl; } void print2(int* val [[carries_dependency]]) { std::cout << *val << std::endl; } int main() { int x{42}; std::atomic<int*> p = &x; int* local = p.load(std::memory_order_consume); if (local) { // The dependency is explicit, so the compiler knows that local is // dereferenced, and that it must ensure that the dependency chain // is preserved in order to avoid a fence (on some architectures). std::cout << *local << std::endl; } if (local) { // The definition of print is opaque (assuming it is not inlined), // so the compiler must issue a fence in order to ensure that // reading *p in print returns the correct value. print(local); } if (local) { // The compiler can assume that although print2 is also opaque then // the dependency from the parameter to the dereferenced value is // preserved in the instruction stream, and no fence is necessary (on // some architectures). Obviously, the definition of print2 must actually // preserve this dependency, so the attribute will also impact the // generated code for print2. print2(local); } }
Mögliche Ausgabe
42 42 42
[bearbeiten] Referenzen
- C++23 Standard (ISO/IEC 14882:2024)
- 9.12.4 Carries dependency attribute [dcl.attr.depend]
- C++20 Standard (ISO/IEC 14882:2020)
- 9.12.3 Carries dependency attribute [dcl.attr.depend]
- C++17 Standard (ISO/IEC 14882:2017)
- 10.6.3 Carries dependency attribute [dcl.attr.depend]
- C++14 Standard (ISO/IEC 14882:2014)
- 7.6.4 Carries dependency attribute [dcl.attr.depend]
- C++11 Standard (ISO/IEC 14882:2011)
- 7.6.4 Carries dependency attribute [dcl.attr.depend]
[bearbeiten] Siehe auch
| (C++11)(veraltet in C++26) |
entfernt das angegebene Objekt aus dem Abhängigkeitsbaum von std::memory_order_consume (Funktions-Template) |