最終更新日時(UTC):
が更新

履歴 編集

コード内容の仮定をコンパイラに伝えるassume属性(C++23)

概要

あるコード地点において実行時に満たすべき仮定(assumption)を、C++コンパイラへ最適化ヒントとして与える属性である。 assume属性を適切に用いると、C++コンパイラはより高速に動作し、サイズの小さいプログラムを生成する可能性がある。

仕様

[[assume(expr)]]属性は、空文(null statement)に対して指定できる。

exprの評価結果はbool型に変換され、その結果がtrueであるとみなされるが、assume属性中の式は効果を持たない。 式exprfalseになる場合は、未定義の動作を引き起こす。

exprには、構文要素 conditional-expression を指定する。 トップレベルのコンマ演算子,や代入演算子=は指定できない。

[[assume(expr1, expr2)]];  // Error
[[assume((expr, expr2))]]; // OK(expr2==trueのみ考慮される)
[[assume(x = 1)]];   // Error
[[assume((x = 1))]]; // OK(効果を持たない)

exprtrueに評価される場合、[[assume(expr)]]属性を指定した空文をコア定数式とみなせる。

int divide_by_32(int x)
{
  [[assume(x >= 0)]];
  // 引数 x は必ず正の値を取ると仮定できるため
  // C++コンパイラによるアセンブリコード生成時に、
  // 非正値を考慮しない最適コードを生成できる可能性がある。
  return x / 32;
}
// asssume属性による仮定がfalseとなる関数呼び出し、
// 例えば divide_by_32(-100) は未定義動作を引き起こす。

int f(int y)
{
  // 効果を持たないため変数 y の値は変化しない。
  [[assume(++y == 43)]];
  // 最適化により return 42; へと置換される可能性がある。
  return y;
}

この機能が必要になった背景・経緯

主要C++コンパイラでは独自拡張として同等機能を提供しており、高パフォーマンスや低レイテンシなアプリ開発向けでは有用であるため、C++標準の属性として採用された。

関連項目

参照