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

履歴 編集

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

このページはC++23に採用された言語機能の変更を解説しています。

のちのC++規格でさらに変更される場合があるため関連項目を参照してください。

概要

あるコード地点において実行時に満たすべき仮定(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++標準の属性として採用された。

関連項目

参照