Namespaces
Variants

C++ attribute: carries_dependency (since C++11) (removed in C++26)

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous
Attributes
(C++23)
carries_dependency
(C++11) (until C++26)
(C++14)
(C++20)
(C++17)
(C++11)
(C++20)

Gibt an, dass die Abhängigkeitskette in Release-Consume std::memory_order in die Funktion hinein und aus ihr heraus propagiert, was dem Compiler erlaubt, unnötige Memory-Fence-Befehle zu überspringen.

Inhaltsverzeichnis

Syntax

[ [ carries_dependency ] ]

Erklärung

Dieses Attribut kann in zwei Situationen auftreten:

1) Es kann auf die Parameterdeklarationen einer Funktion oder Lambda-Ausdrücke angewendet werden, in welchem Fall es anzeigt, dass die Initialisierung des Parameters eine Abhängigkeit in die Lvalue-zu-Rvalue-Konvertierung dieses Objekts überträgt.
2) Es kann auf die Funktionsdeklaration als Ganzes angewendet werden, wobei es anzeigt, dass der Rückgabewert eine Abhängigkeit von der Auswertung des Funktionsaufrufausdrucks trägt.

Dieses Attribut muss bei der ersten Deklaration einer Funktion oder eines ihrer Parameter in jeder Übersetzungseinheit erscheinen. Wenn es nicht bei der ersten Deklaration einer Funktion oder eines ihrer Parameter in einer anderen Übersetzungseinheit verwendet wird, ist das Programm fehlerhaft; keine Diagnose erforderlich.

Beispiel

Fast unverändert übernommen von SO .

#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

Referenzen

  • C++23-Standard (ISO/IEC 14882:2024):
  • 9.12.4 Carries dependency-Attribut [dcl.attr.depend]
  • C++20-Standard (ISO/IEC 14882:2020):
  • 9.12.3 Carries dependency-Attribut [dcl.attr.depend]
  • C++17-Standard (ISO/IEC 14882:2017):
  • 10.6.3 Carries dependency-Attribut [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-Attribut [dcl.attr.depend]

Siehe auch

(C++11) (deprecated in C++26)
entfernt das angegebene Objekt aus dem std::memory_order_consume Abhängigkeitsbaum
(Funktionsschablone)