私はstd::gcd
予期しないことに気付いたこの振る舞いに遭遇しました:
#include <iostream>
#include <numeric>
int main()
{
int a = -120;
unsigned b = 10;
//both a and b are representable in type C
using C = std::common_type<decltype(a), decltype(b)>::type;
C ca = std::abs(a);
C cb = b;
std::cout << a << ' ' << ca << '\n';
std::cout << b << ' ' << cb << '\n';
//first one should equal second one, but doesn't
std::cout << std::gcd(a, b) << std::endl;
std::cout << std::gcd(std::abs(a), b) << std::endl;
}
cppreferenceによると、すべての前提条件が満たされているstd::gcd
ため10
、への両方の呼び出しでが生成されます。
特に、両方のオペランドの絶対値が共通の型で表現可能であることのみが必要です。
| m |の場合 または| n | タイプの値として表現できない
std::common_type_t<M, N>
場合、動作は未定義です。
しかし、最初の呼び出しは戻ります2
。ここで何か不足していますか?gccとclangの両方がこのように動作します。
興味深いことに、gccは2つのintをコンパイルして値を出力するだけですが、intとunsignedはそうではありません。godbolt.org
—
Alan Birtles
なに
—
TC
-120 % 10u
?(ヒント:0ではありません。)はい、バグです。
@TCはい、キャスティング
—
dave
-120
にunsigned
になり4294967176
た% 10u
です 6
。私の質問はむしろ、この振る舞いが実際に正しくないかどうかでした。
@AlanBirtlesその場合、そこにはキャストされ
—
dave
unsigned
ないため、バグも発生しません