首先,我想说的是我知道在C++中,char、signed char和unsigned char是不同的类型。根据标准的快速阅读,char是否为signed是由实现定义的。而且让事情变得更有趣的是,似乎g++会根据平台决定char是否为signed!所以,有了这个背景,让我们介绍一下我在使用这个玩具程序时遇到的一个bug:
预期行为是两次对
修复此错误似乎很容易,我只需要将
#include <stdio.h>
int main(int argc, char* argv[])
{
char array[512];
int i;
char* aptr = array + 256;
for(i=0; i != 512; i++) {
array[i] = 0;
}
aptr[0] = 0xFF;
aptr[-1] = -1;
aptr[0xFF] = 1;
printf("%d\n", aptr[aptr[0]]);
printf("%d\n", aptr[(unsigned char)aptr[0]]);
return 0;
}
预期行为是两次对
printf
的调用都应输出1。当然,在运行在linux/x86_64
上的gcc
和g++ 4.6.3
上,第一个printf
输出-1,而第二个输出1。这与chars被视为有符号并且g++
合理地解释了-1(这在技术上是未定义的行为)一致。修复此错误似乎很容易,我只需要将
char
强制转换为unsigned
,如上所示。我想知道的是,这段代码是否曾经预期在使用gcc/g++
的x86或x86_64机器上正常工作?显然,在ARM平台上可能按预期工作,因为chars显然是无符号的,但我想知道这段代码在使用g++
的x86机器上是否一直存在缺陷?
char
类型具有你所喜欢的任何有符号性。它存在的目的正是为了解决像这样非可移植错误的代码。 :) - Lightness Races in Orbit