Namespaces
Variants

C++ attribute: assume (since C++23)

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

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

目次

翻訳の説明: - 「Contents」を「目次」に翻訳しました - HTMLタグ、属性、
タグ内のテキストは翻訳していません
- C++固有の用語(Syntax、Explanation、Notes、Example、Defect reports、References、See also、External links)は原文のまま保持しています
- 数値や書式設定は完全に保持されています

構文

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

説明

[ [ assume ] ] null文 にのみ適用でき、例えば [ [ assume ( x > 0 ) ] ] ; のように記述します。この文は アサンプション と呼ばれます。

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

  • 変換された expression が、その仮定が現れる時点で true と評価される場合、その仮定は効果を持たない。
  • それ以外の場合、仮定の評価は runtime-undefined behavior を持つ。

注記

仮定が成り立たない場合、実行時未定義動作を引き起こすため、仮定は控えめに使用すべきです。

それらを使用する正しい方法の1つは、アサーションの後に前提条件を続けることです:

assert(x > 0);     // NDEBUGが定義されていない場合にx > 0がfalseのときアサーションをトリガーする
[[assume(x > 0)]]; // NDEBUGが定義されている場合に最適化の機会を提供する

#include <cmath>
void f(int& x, int y)
{
    void g(int);
    void h();
    [[assume(x > 0)]]; // コンパイラはxが正であると仮定する可能性がある
    g(x / 2); // より効率的なコードが生成される可能性がある
    x = 3;
    int z = x;
    [[assume((h(), x == z))]]; // コンパイラはh呼び出し後もxが同じ値を持つと仮定する可能性がある
                               // この仮定はhの呼び出しを引き起こさない
    h();
    g(x); // コンパイラはこれをg(3)に置き換える可能性がある
    h();
    g(x); // コンパイラはこれをg(3)に置き換えることはできない
          // 仮定はそれが現れる時点でのみ適用される
    z = std::abs(y);
    [[assume((g(z), true))]]; // コンパイラはg(z)が戻ると仮定する可能性がある
    g(z); // 上記および下記の仮定により、コンパイラはこれをg(10)に置き換える可能性がある
    [[assume(y == -10)]]; // この時点でy != -10の場合、未定義動作
    [[assume((x - 1) * 3 == 12)]];
    g(x); // コンパイラはこれをg(5)に置き換える可能性がある
}

不具合報告

以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。

DR 適用対象 公開時の動作 正しい動作
CWG 2924 C++23 仮定の違反は未定義動作を引き起こす 実行時未定義動作を引き起こす

参考文献

  • C++23標準 (ISO/IEC 14882:2024):
  • 9.12.3 仮定属性 [dcl.attr.assume]

関連項目

実行不可能なポイントをマークする
(関数)
contract_assert (C++26) 実行中の内部条件を検証する

外部リンク

1. Clang言語拡張ドキュメント: __builtin_assume .
2. Clang属性リファレンスドキュメント: assume .
3. MSVCドキュメント: __assume 組み込み関数.
4. GCCドキュメント: __attribute__((assume(...))) .