我遇到了我的代码的错误行为。研究它使我得到一个简短的示例,该示例显示了问题:
//g++ 5.4.0
#include <iostream>
#include <vector>
int main()
{
std::vector<short> v(20);
auto D = &v[5] - &v[10];
auto C = D / sizeof(short);
std::cout << "C = " << C;
}
这个例子很常见。它将显示什么结果?
C = 9223372036854775805
在这里测试:https://rextester.com/l/cpp_online_compiler_gcc还针对Clang C ++,VS C ++和C进行了测试。结果相同。
与同事讨论时,我指向文档https://en.cppreference.com/w/cpp/language/operator_arithmetic#Conversions。
它告诉:
似乎second规则在这里起作用。但这是not正确。
为了确认second规则,我已经测试过这样的示例:
//g++ 5.4.0
#include <iostream>
int main()
{
typedef uint32_t u_t; // uint64_t, uint32_t, uint16_t uint8_t
typedef int32_t i_t; // int64_t, int32_t, int16_t int8_t
const u_t B = 2;
const i_t X = -1;
const i_t A1 = X * B;
std::cout << "A1 = X * B = " << A1 << "\n";
const i_t C = A1 / B; // signed / unsigned division
std::cout << "A1 / B = " << C << "\n";
}
具有u_t和i_t的不同<< rank >>组合,发现它对于任何组合均正常工作,对于32和64位,EXCEPT (int64_t / uint64_t和int32_t / uint32_t)。因此second规则DOES NOT适用于16和8位。注意: 乘法 SECOND有符号操作数被转换为无符号操作数的类型
The
signed无法转换为unsigned-它是!!错误!!表示NEGATIVE值!但是相反的转换是正确的-无符号操作数被转换为有符号操作数的类型看这一点,我可以注意到,这是C ++标准算术运算中可能存在的错误。代替:
Otherwise, if the unsigned operand's conversion rank is greater or equal to the conversion rank of the signed operand, the signed operand is converted to the unsigned operand's type.
应该是:
Otherwise, if the signed operand's conversion rank is greater or equal to the conversion rank of the unsigned operand, the unsigned operand is converted to the signed operand's type.
我认为,如果满足
signed
和unsigned multiplication / division,则将unsigned操作数转换为signed,然后投放到正确的等级。至少跟随x86 Assembler。[,请告诉我这是哪里错误。我希望这篇文章中的第一个测试对于代替auto
类型涉及的任何类型都适用,但是现在[#include
int main(){std :: ...