【发布时间】:2021-07-20 16:22:47
【问题描述】:
在 arm64 上测试我的软件时遇到了一个奇怪的问题。
我写了一些代码来重现这个问题:
char c;
int sum = 0;
for (int i = 0; i <= 255; i++)
{
c = i;
int a = c * 10;
sum += a;
std::cout << a << std::endl;
}
当我在 Windows(使用 Visual Studio 2017 构建)或 Ubuntu x64(gcc 9.3.0-17)上运行它时,我得到以下结果:
0
10
...
1260
1270
-1280
-1270
-20
-10
sum=-1280
如果我在 Ubuntu arm64 (gcc 9.3.0-17) 上运行相同的代码,我会得到不同的结果:
0
10
...
1260
1270
1280
1290
...
2540
2550
sum=326400
我不知道在 arm64 上的 gcc 中是否有一些额外的优化(使用 -O3)或者是否有一些我看不到的问题?关于如何解决此问题的任何想法?
【问题讨论】:
-
也许你应该在arm平台上检查
char是有符号还是无符号类型,而不是假设它。请注意,char是与signed char和unsigned char不同的类型。 -
不是硬件;决定签名和溢出行为的是编译器。
-
@alfC 我认为 OP 已经 not 首先转换为
int,以便重现该问题。他们的“现实世界”代码可能更加微妙/复杂。 -
@alfC 另外,在您的建议中,
static_cast<int>(c)为时已晚 - 之前的语句中已经发生了赋值和(可能)溢出。 -
char可以是有符号或无符号的,在 ARM 上通常默认为无符号,而大多数架构默认使用有符号字符:Why unsigned types are more efficient in arm cpu?、Is char signed or unsigned by default?、is char signed or unsigned by default on iOS?。在 gcc 中,可以使用-funsigned-char或-fsigned-char更改 char 的符号