1

単純な utf8 strlen 関数をテストしたところ、trunk clang がそれを完全に排除したことに非常に驚きました (gcc はそうではありません):

static int strlenutf8(const char* s)
{
  int i = 0, l = 0;
  while (s[i])
  {
    if ((s[i] & 0xc0) != 0x80) l++;
    l++;
  }
  return j;
}

int main()
{
    return strlenutf8("bla");
}

clang++ -O3 -S -fverbose-asm:

main:                                   # @main
    .cfi_startproc
# BB#0:                                 # %entry
    movl    $3, %eax
    ret

これは、D のコンパイル時の関数評価に似ています。これは C++ でも合法ですか?

つまり、そもそも彼らがそのくだらないconstexprを発明したのには理由があるに違いありません。厳しく制限されているため、私の知る限り、ここでは使用できませんでした。

4

3 に答える 3

3

constexpr定数式のコンテキスト (テンプレートの引数推定など) にのみ必要ですが、constexpr関数がコンパイル時に評価されることは保証されていません。

C++ プログラムを最適化するための黄金律は、次のas-if規則です。

この国際標準のセマンティック記述は、パラメータ化された非決定論的抽象マシンを定義します。この国際規格は、適合する実装の構造に要件を課していません。特に、抽象マシンの構造をコピーまたはエミュレートする必要はありません。むしろ、以下で説明するように、抽象マシンの観察可能な動作をエミュレートする (のみ) ために、適合する実装が必要です。

非常に必要な脚注で:

この規定は「as-if」ルールと呼ばれることもあります。これは、観察可能な動作から判断できる限り、結果があたかも要件に従っているかのようである限り、実装はこの国際規格の要件を自由に無視できるためです。プログラムの。たとえば、実際の実装では、式の値が使用されておらず、プログラムの観察可能な動作に影響を与える副作用がないと推測できる場合、式の一部を評価する必要はありません。

主要なBUT : 副作用のあるコピー コンストラクター (たとえば、"コピー コンストラクターと呼ばれる" カウント変数または同等のものをインクリメントする) は、"as-if" に含める必要はありません。これは以下に含まれてい12.8/31ます:

特定の基準が満たされると、オブジェクトのコピー/移動コンストラクターおよび/またはデストラクタに副作用がある場合でも、実装はクラス オブジェクトのコピー/移動構築を省略できます。このような場合、実装は、省略されたコピー/移動操作のソースとターゲットを、同じオブジェクトを参照する 2 つの異なる方法として扱い、そのオブジェクトの破棄は、2 つのオブジェクトが削除されていた時間のうちの遅い方の時点で発生します。最適化なしで破棄されます。

于 2013-04-24T15:31:50.543 に答える
2

この最適化を検出する標準準拠の C++ プログラムをどのように作成しますか? 方法が思い浮かばない場合は、最適化で問題ありません (まあ、方法がなければ問題ありません)。コンパイラは、生成されたコードを見るだけで非効率な処理を行う必要はありません。

于 2013-04-24T16:02:48.930 に答える
2

コンパイル時に式を評価することでサポートするには、適合する C++ コンパイラが必要です。constexprconstexpr式のコンパイル時の評価は、as-if 規則によって許可されます。strlenutf8関数には (目に見える) 副作用がないため、コンパイラはそれを省略できます。

于 2013-04-24T15:30:48.810 に答える