LoginSignup
15
5

More than 5 years have passed since last update.

鼻から悪魔:不定値(indeterminate value)バージョン

Last updated at Posted at 2016-11-19

問:次のC++プログラムの実行結果は?

#include <cstdio>

#define NUMBER 42

static
void func(int& rv)
{
  int local = rv;
  if (local == NUMBER) {
    std::puts("hit");
  } else {
    std::puts("stay");
  }
}

int main()
{
  int v; // indeterminate value
  func(v);
}

答え:

は?clangなにやってんの?

clangの場合、マクロNUMBER任意の数値にかえたとしても結果はhitになります。

一方のgccは何となく正しいようにも思えますかね?

コンパイラのバグだろ?

いいえ、C++ソースコードのバグです。悔い改めてください。

変数vは不定値(indeterminate value)であり、参照rvを介した変数v読み取りは未定義動作(undefined behavior)を引き起こします。未定義動作を含むC++プログラムでは、いかなることが起きようともそれはC++言語仕様に準じた振る舞いであり、全ては誤ったC++ソースコードを記述したプログラマの責任です。つらい。

コンパイル結果(出力アセンブリ)を覗く

gcc 6.1(x86-64), -O2オプション無条件にstayを出力します。hitに関する処理は消失しています。

.LC1:
        .string "stay"
main:
        subq    $8, %rsp
        movl    $.LC1, %edi
        call    puts
        xorl    %eax, %eax
        addq    $8, %rsp
        ret

Clang 3.9.0(x86-64), -O2オプション無条件にhitを出力します。stayに関する処理は消失しています。

main:
        pushq   %rax
        movl    $.L.str, %edi
        callq   puts
        xorl    %eax, %eax
        popq    %rcx
        retq
.L.str:
        .asciz  "hit"

鼻から悪魔の世界へようこそ。

関連POST

一連の「null安全」話にインスパイアされた記事ですが、正直言って直接的には関係しません。C/C++言語系の未定義動作は怖いという実例として。

15
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
5