Aks*_*sel 1 c++ arm uint64 armv7
在uint64_t和long的混合上使用算术会在arm(C ++编译器)上产生不需要的结果。相同的代码可以在x86上正常工作。
如果将long替换为uint64_t,则它将按预期工作。
Armv7编译器是C ++(Debian 6.3.0-18 + deb9u1)6.3.0 20170516
这里的代码也:http : //cpp.sh/2xrnu
int main()
{
uint64_t x = 1000UL * 60 * 60 * 24 * 31;
int i1 = 31;
long l2 = 1000 * 60 * 60 * 24;
uint64_t u2 = 1000 * 60 * 60 * 24;
std::cout << "x : " << x << std::endl;
std::cout << "i1 : " << i1 << std::endl;
std::cout << "l2 : " << l2 << std::endl;
std::cout << "u2 : " << u2 << std::endl;
std::cout << "x - i1*l2: " << x - i1 * l2 << std::endl; // expected '0', got 4294967296
std::cout << "x - i1*u2: " << x - i1 * u2 << std::endl; // expected and got '0'
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我希望最后两行给出“ 0”。
在x86上,结果是
i1 : 31
l2 : 86400000
u2 : 86400000
x - i1*l2: 0
x - i1*u2: 0
Run Code Online (Sandbox Code Playgroud)
在Arm(CortexA8)上,结果是
i1 : 31
l2 : 86400000
u2 : 86400000
x - i1*l2: 4294967296
x - i1*u2: 0
Run Code Online (Sandbox Code Playgroud)
在这行代码中:
std::cout << "x - i1*l2: " << x - i1 * l2 << std::endl; // expected '0', got 4294967296
Run Code Online (Sandbox Code Playgroud)
当您将31乘以86400000时,将得到2678400000,即0x9FA52400,它不适合4个字节的有符号长整数(符号位设置为1)。然后,由于有符号溢出和垃圾值转换为uint64_t从x减去UB而得到UB 。在x86上,您显然有更大的long感觉,您看不到问题。