我们刚刚在我们的应用程序的 Android 版本中偶然发现了一个错误,该错误是由 iOS 和 Android 上的编译器差异引起的。好奇是否有人可以解释差异以及如何使 Android native C 编译器像 iOS 一样工作。这是问题的简化版本。
double zone = -7 / 24.0;
char command[80] = { '\0' };
//其他东西
command[7] = zone * 24.0;
忽略上述可能的舍入误差。这是一个简化的例子。
在 iOS 上,command[7] 获取输入的值 -7。这是我所期望的,因为在执行分配时应该自动从 double 转换为 char(或 int)。
在 Android 上,使用原生 C 编译器,我们将 0 放入命令 [7]。如果我们像这样显式地转换它
command[7] = (int)(zone * 24.0);
然后得到和iOS一样的结果。
有谁知道为什么这两个编译器会生成不同的代码?如果 Android 上有一个编译器标志可以使编译器的行为与 iOS 中的一样?该应用已经在 iOS 上进行了广泛的测试,我们对这个问题有点怀疑。
Best Answer-推荐答案 strong>
在您的 Android C 实现中,char 是无符号的,从 double 中的 -7 到 char 的转换产生零。 (当值不能以目标类型表示时,此转换的行为未由 C 标准定义。)
在 iOS 中,char 是有符号的,double 中的 -7 到 char 的转换产生 -7。
编译器可能有一个 -fsigned-char 开关可以使 char 签名,或者您可以更改 char command[80]… 到 signed char command[80]… .
这就解释了为什么 command[7] = (int)(zone * 24.0); 会得到想要的结果:
- 在将结果分配给
command[7] 之前将结果转换为 int 时,double 中的 -7 将转换为 -7在 int 中。然后这个 int 被转换成一个无符号 char 。该转换由 C 标准定义,结果为 CHAR_MAX+1-7(在典型的 C 实现中使用无符号 char 为 249)。这在 iOS (-7) 和 Android (249) 上的结果不同,但它们用相同的位表示。据推测,无论您进一步使用它们,它们的行为都是相同的。
关于android - iOS 和 Android 开发的 C 编译器差异,我们在Stack Overflow上找到一个类似的问题:
https://stackoverflow.com/questions/21467195/
|