読者です 読者をやめる 読者になる 読者になる

VS2013で遭遇した最悪なバグ

自分が遭遇した最悪なバグを書いておこうと思う

型破壊バグ
std::cout << typeid(BreakType).name();//struct ??::??と出力される
//error C2133:サイズが不明です
//error C2512:コンストラクタがない
BreakType c;

上記のように壊れた型が発生する

初代ポケモンのケツバンを感じる
壊れた型をstd::is_sameすると「定数式ではない」と言われたりするが、結構コンパイルをすり抜けるのでツライ

この壊れた型は以下のようにして発生させた

template<class ...T>
struct List{};

template<class...T>
List<typename T::type...> break_f(List<T...>);

using BreakType = decltype(break_f(List<std::true_type, std::true_type>{}));

VSでテンプレート引数に::typeするのとパラメータパック展開するのはなぜかバグってエラーになる。が上記のとおり関数の宣言内だとなぜか通ったりする

しかし、通った結果が型破壊バグなのでパラメータパック展開とT::typeを組み合わせるのはやめよう
回避するにはT::typeを返すメタ関数Fを作り使うことだと思う
List:::type...>

宣言する順番で結果が変わるバグ
std::cout << logic<List1>::type::value;//1
std::cout << logic<List2>::type::value;//0
std::cout << logic<List2>::type::value;//1
std::cout << logic<List1>::type::value;//0

なぜか宣言する順番で結果が変わるバグ
このバグが現れるまで個人的最強最悪バグは上記の型破壊バグが有していた
だがこのバグは恐ろしく静かで、しかも意味不明なバグでありキンブオブ最悪バグとなった

このバグはallを実装するときに発生した

template<class list>
class logic
{
	template<class...T>
	static std::true_type impl(List<std::integral_constant<T, 1>...>);
	static std::false_type impl(...);
public:
	using type = decltype(impl(list{}));
};
using List1 = List<std::true_type, std::true_type>;
using List2 = List<std::true_type>;

このプログラムは正常に動けばどちらも1を返すべきである。しかしなぜか後に評価された方は0を返す。理由は不明


回避法は(そもそも遭遇しないと思うが)別の実装法をすることである