【发布时间】:2018-01-21 13:10:15
【问题描述】:
我正在迁移旧 C++ 代码的某些部分,这些代码最初是使用 CodeGear C++Builder® 2009 版本 12.0.3170.16989 编译的
以下代码 - 较大部分的最小版本 - 使用任何现代编译器输出 -34。虽然,在原来的平台上它输出84:
char Key[4];
Key[0] = 0x1F;
Key[1] = 0x01;
Key[2] = 0x8B;
Key[3] = 0x55;
for(int i = 0; i < 2; i++) {
Key[i] = Key[2*i] ^ Key[2*i + 1];
}
std::cout << (int) Key[1] << std::endl;
for(int i = 0; i < 2; i++) {
char a = Key[2*i];
char b = Key[2*i + 1];
char c = a ^ b;
Key[i] = c;
}
此外,手动展开循环似乎适用于两种编译器:
Key[0] = Key[0] ^ Key[1];
Key[1] = Key[2] ^ Key[3];
我匹配旧代码的行为很重要。谁能帮我理解为什么原始编译器会产生这些结果?
【问题讨论】:
-
编译标志有符号/无符号字符???
-
如果我将
char更改为unsigned char,这将产生 222。 (这是有道理的,因为这是 8 位 -34 的 2 的补码值) -
为了调试,能不能改一下代码,用原来的CodeGear编译器重新编译?因为我看到尽管代码说了什么,但看起来正在执行的是
Key[1] = Key[1] ^ Key[3],因为结果为 84。 -
我希望在我提交此评论的第二次被证明是错误的,但它对我来说就像一个编译器错误 - 如果这是合法行为,那么 c++ 整数提升/转换规则比我想象的还要疯狂.最坏的情况:创建一个复制原始编译器错误行为的查找表(并记录其中的垃圾)。
-
看来我可以用 Key[i]=Key[i]^Key[2*i+1] 重现原始行为(删除
2*),正如@lxop 所建议的那样,但我真的不明白这里发生了什么。
标签: c++ c++builder c++builder-2009