名前空間
変種
操作

C++ 属性: carries_dependency (C++11 以降)(C++26 で削除)

From cppreference.com
< cpp‎ | language‎ | attributes
 
 
C++言語
全般
フロー制御
条件実行文
if
繰り返し文 (ループ)
for
範囲for (C++11)
ジャンプ文
関数
関数宣言
ラムダ式
inline指定子
動的例外仕様 (C++17まで*)
noexcept指定子 (C++11)
例外
名前空間
指定子
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
記憶域期間指定子
初期化
代替表現
リテラル
ブーリアン - 整数 - 浮動小数点数
文字 - 文字列 - nullptr (C++11)
ユーザー定義 (C++11)
ユーティリティ
属性 (C++11)
typedef宣言
型エイリアス宣言 (C++11)
キャスト
メモリ確保
クラス
クラス固有の関数プロパティ
explicit (C++11)
static

特殊メンバ関数
テンプレート
その他
 
 
属性
(C++23)
carries_dependency
(C++11)(C++26 まで)
(C++14)
(C++20)
(C++17)
(C++11)
(C++20)
 

release-consume std::memory_order の依存関係チェーンが関数の内外に伝播することを示し、コンパイラが不要なメモリフェンス命令をスキップできるようにします。

目次

[編集] 構文

[[carries_dependency]]

[編集] 説明

この属性は、次の2つの状況で使用できます。

1) 関数の仮引数宣言、またはラムダ式に適用される場合、仮引数の初期化がそのオブジェクトの左辺値から右辺値への変換に依存関係を伝播することを示します。
2) 関数宣言全体に適用される場合、戻り値が関数呼び出し式の評価に依存関係を伝播することを示します。

この属性は、任意の翻訳単位において、関数またはその仮引数の最初の宣言に現れなければなりません。別の翻訳単位において、関数またはその仮引数の最初の宣言にそれが使用されていない場合、プログラムは不正です。診断は不要です。

[編集]

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);
    }
}

実行結果の例

42
42
42

[編集] 参照

  • C++23標準 (ISO/IEC 14882:2024)
  • 9.12.4 依存関係属性 [dcl.attr.depend]
  • C++20 standard (ISO/IEC 14882:2020)
  • 9.12.3 依存関係属性 [dcl.attr.depend]
  • C++17 standard (ISO/IEC 14882:2017)
  • 10.6.3 依存関係属性 [dcl.attr.depend]
  • C++14 standard (ISO/IEC 14882:2014)
  • 7.6.4 依存関係属性 [dcl.attr.depend]
  • C++11 standard (ISO/IEC 14882:2011)
  • 7.6.4 依存関係属性 [dcl.attr.depend]

[編集] 関連項目

(C++11)(C++26で非推奨)
std::memory_order_consume 依存関係ツリーから指定されたオブジェクトを削除する
(関数テンプレート) [編集]
English 日本語 中文(简体) 中文(繁體)