テストコードはこれ。
valueless_by_exception と出力されるのを期待しているが、実際には 0.2 という空になる前の値を出力している。
{
PrintToLogChecker ck("valueless_by_exception");
::std::variant<int, ::std::string, float> v = 0.2f;
try
{
struct S { operator int() { throw 42; } };
v.emplace<0>(S());
}
catch(...)
{
}
IUTEST_SUCCEED() << ::iutest::PrintToString(v);
}
この valueless にするコードは、
https://ja.cppreference.com/w/cpp/utility/variant/valueless_by_exception からとってきたもので、今までは valueless になっていたのを確認している。
関連するコードをいじってはいないので、環境周りの違いだと思い確認したところ、g++ 9.1.0 では valueless にならないことを確認しました。
また、valueless な状態を作る方法を探していたら、
https://cpprefjp.github.io/reference/variant/variant/valueless_by_exception.html に AlwaysThrow でのサンプルがあったので、そちらを使って確認したところ g++ 9.1.0 でも valueless になりました。
(typo がひでぇ)gcc 9.1.0 [Wandbox]三へ( へ՞ਊ ՞)へ ハッハッ https://t.co/m7V6DImr9E— ずみっくす :D (@srz_zumix) 2019年5月11日
g++ 9.1.0 は前者のパターンは valueless ならず。
— ずみっくす :D (@srz_zumix) 2019年5月11日
以前の値が残ってるみたいだけど、この挙動はなんかハマりそうな気がしないでもない。
よって、テストコードとりあえず以下のように修正しました。
{
PrintToLogChecker ck("valueless_by_exception");
::std::variant<int, float, AlwaysThrow> v = 0.2f;
try
{
struct S { operator int() { throw 42; } };
v.emplace<0>(S());
}
catch(...)
{
IUTEST_INFORM_TRUE(v.valueless_by_exception());
}
if( !v.valueless_by_exception() )
{
try
{
v = AlwaysThrow();
}
catch(...)
{
IUTEST_INFORM_TRUE(v.valueless_by_exception());
}
}
IUTEST_SUCCEED() << ::iutest::PrintToString(v);
}
これはバグ?
cpprefjp も cppreference.com も、サンプルのコメントを読むと、確実に valueless な状態にはなるとは限らないように読み取れるのだが、(規格的に)これはそういうもんなのだろうか?それとも g++ 9.1.0 のバグなのだろうか?一旦ここまでで記事公開させていただきます。
続報あれば、追記していきますmm
0 件のコメント:
コメントを投稿