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

履歴 編集

確率が高い分岐と低い分岐を伝える属性 [[likely]], [[unlikely]](C++20)

概要

if文やswitch文といった分岐制御構文において、条件分岐先のうちどれが実行される可能性が高いかという情報を、C++コンパイラへ最適化ヒントとして与える属性である。 これらの属性を適切に用いると、C++コンパイラはより高速に動作するプログラムを生成する可能性がある。

[[likely]], [[unlikely]]属性はあくまでヒント情報にすぎないため、C++コンパイラはこれらを完全に無視するかもしれない。 また実際にどの程度の効果がえられるかは、C++コンパイラの最適化性能、動作環境のCPUアーキテクチャなどに依存する。

仕様

[[likely]], [[unlikely]]属性は、ラベル または 文 に対して指定できる。 ある要素に対して[[likely]][[unlikely]]を同時指定してはならない。

bool process()
{
  if (!do_preprocess()) [[unlikely]] {
    // (めったに失敗しないが)サブ処理に失敗したらfalseを返す
    return false;
  }

  // 何らかのメイン処理

  if (!do_postprocess()) [[unlikely]] {
    // (めったに失敗しないが)サブ処理に失敗したらfalseを返す
    return false;
  }

  // 正常終了はtrueを返す
  return true;
}

std::string fizzbuzz(int n)
{
  using namespace std::string_literals;
  switch (n % 15) {
  case 3: case 6: case 9: case 12:
    return "Fizz"s;
  case 5: case 10:
    return "Buzz"s;
  case 0:
    return "FizzBuzz"s;
  [[likely]] default:
    return std::format("{}", n);
  }
}
// 上記例のlikely属性利用は適切ではない可能性もあり、
// switch文ラベルへ属性指定構文例示として解釈すること。
// 入力nがランダムと仮定すると 8/15=53.3% の分岐確率となり、
// この程度の偏りに対して最適化効果が得られるかは未知数である。

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

GCCやClangなど一部C++コンパイラでは独自拡張として同等機能を提供しており、Linuxカーネルや大規模OSSによる広い利用実績があったため、C++標準の属性として採用された。

関連項目

参照