Edited at

C++の未定義動作でa==1&&a==2&&a==3をtrueにしてみたい


はじめに

@tyu_ru_cpp さんの書かれた記事『C++でa == 1 && a == 2 && a == 3をtrueにしてみたい(クソ解法)』のブラッシュアップ版みたいなやつです。

2年近く前に流行ったネタですね。


コードの紹介

Cに見えますがC++です。


hoge.cpp

#include <stdio.h>


int test(volatile int a)
{
if (a == 1 && a == 2 && a == 3) {
puts("true");
return 0;
}
}

int main()
{
int a = 0;
test(a);
}



コンパイルと実行結果

$ g++ -w -O2 hoge.cpp ; ./a.out

true
$

Wandboxで実行


動作の解説

未定義動作の解説というのもナンセンスな話ですが一応。

@kaityo256 さんの書かれた記事『MacのGCCで返り値を返さない関数を書くと鼻から悪魔が出る』のコメントにある最適化が働いている模様です。

int の値を返す関数 test の中の条件式a == 1 && a == 2 && a == 3が false となった場合、return 式;がないまま関数の処理が終了してしまうことになりますが、C++ の仕様的に未定義動作となってしまうためそれはあり得んだろうということでコンパイラの最適化の働きでその分岐は削除され、結果的にa == 1 && a == 2 && a == 3は常に true ということにしてしまうようです。

以上の動作は g++ では ver.8 以上clang++ では ver.3.2 以上で確認できます。clang++ ver.4 以上ではこの最適化を抑止する -fno-strict-returnというコンパイルオプションも用意されており、効果も確認できます


おわりに

おわりです。