名前空間
変種
操作

C++ 属性: assume (C++23 以降)

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

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

指定された式が特定の時点で常に true に評価されると仮定し、与えられた情報に基づいてコンパイラ最適化を可能にします。

目次

[編集] 構文

[[assume( )]]
- 任意の式 (括弧で囲まれていないコンマ式を除く)

[編集] 説明

[[assume]] は、[[assume(x > 0)]; のように、ヌルステートメントにのみ適用できます。このステートメントは assumption と呼ばれます。

文脈的に bool に変換されますが、評価はされません (依然として評価される可能性はあります)。

  • 変換された が assumption が現れる時点で true に評価される場合、その assumption は効果がありません。
  • そうでなければ、assumption の評価は実行時未定義動作となります。

[編集] 注記

assumption が成立しない場合、実行時未定義動作を引き起こすため、注意して使用する必要があります。

これらを使用する正しい方法の1つは、assertion の後に assumption を記述することです。

assert(x > 0);     // trigger an assertion when NDEBUG is not defined and x > 0 is false
[[assume(x > 0)]]; // provide optimization opportunities when NDEBUG is defined

[編集]

#include <cmath>
 
void f(int& x, int y)
{
    void g(int);
    void h();
 
    [[assume(x > 0)]]; // Compiler may assume x is positive
 
    g(x / 2); // More efficient code possibly generated
 
    x = 3;
    int z = x;
 
    [[assume((h(), x == z))]]; // Compiler may assume x would have the same value after
                               // calling h
                               // The assumption does not cause a call to h
 
    h();
    g(x); // Compiler may replace this with g(3);
 
    h();
    g(x); // Compiler may NOT replace this with g(3);
          // An assumption applies only at the point where it appears
 
    z = std::abs(y);
 
    [[assume((g(z), true))]]; // Compiler may assume g(z) will return
 
    g(z); // Due to above and below assumptions, compiler may replace this with g(10);
 
    [[assume(y == -10)]]; // Undefined behavior if y != -10 at this point
 
    [[assume((x - 1) * 3 == 12)]];
 
    g(x); // Compiler may replace this with g(5);
}

[編集] 欠陥報告

以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。

DR 適用対象 公開された動作 正しい動作
CWG 2924 C++23 assumption に違反すると未定義動作になります 実行時未定義動作になります

[編集] 参照

  • C++23標準 (ISO/IEC 14882:2024)
  • 9.12.3 Assumption attribute [dcl.attr.assume]

[編集] 関連項目

実行が到達不能な地点をマークする
(関数) [編集]
contract_assert (C++26) 実行中に内部条件を検証する[編集]

[編集] 外部リンク

1.  Clang 言語拡張ドキュメント: __builtin_assume
2.  Clang 属性リファレンスドキュメント: assume
3.  MSVC ドキュメント: __assume 組み込み関数。
4.  GCC ドキュメント: __attribute__((assume(...)))
English 日本語 中文(简体) 中文(繁體)