我在读一个源代码文件。但我被困在了下面这条线
while (isspace (* bp & 0xff))
++ bp;
我知道基本的想法是移除这些空间。但我不知道0xff
在下面的函数中到底在做什么。
static enum tokens scan (const char * buf)
{
static const char * bp;
if (buf)
bp = buf; /* new input line */
while (isspace (* bp & 0xff))
++ bp;
if (isdigit (* bp & 0xff) || * bp == '.')
{
errno = 0;
token = NUMBER, number = strtod (bp, (char **) & bp);
if (errno == ERANGE)
error ("bad value: %s", strerror (errno));
}
else
token = * bp ? * bp ++ : 0;
return token;
}
发布于 2015-09-19 13:59:43
isspace
函数和另一个ctype.h
函数需要一个int
作为参数。来自C11标准第7.4/1节:
报头声明了几个用于分类和映射字符的函数。在所有情况下,参数都是
int
,其值应表示为EOF
或应等于宏EOF
的值。如果该参数具有任何其他值,则该行为是未定义的。
这意味着,如果您有代码,如:
char ch = 'é'; // same as: char ch = -126; for some code pages
isspace(ch);
然后,此调用将导致undefined behaviour。
这样做的基本原理是可以将函数实现为查找表:#define isspace(x) space_table[x]
。
当然,造成未定义的行为是不好的,所以isspace(ch)
是错误的。修复代码的正确方法是:
isspace( (unsigned char)ch );
在使用2的补码算法的机器上,ch & 0xFF
与(unsigned char)ch
完全等价。
在一台不使用2的补码的机器上,它会查找错误的值(但不会导致未定义的行为)。
也许您的程序员很高兴地认为,他的代码永远不会在非2的补码机器上运行,并为空格设置负字符代码,而且他认为& 0xFF
比强制转换更美观。
发布于 2015-09-19 11:45:30
使用0xFF
计算和操作提取最低字节,假设每字节8位。对非负值没有影响,但char
也可以进行签名,在这种情况下,生成的int
不能用unsigned char
表示;采用最低字节可以解决这个问题。
从技术上讲,在表达式ch & 0xFF
中,操作数被提升为int
,这可能会吓到程序员,因为isspace
的参数是int
,但是值必须适合于unsigned char
或具有只能用int
s表示的值EOF
。
https://stackoverflow.com/questions/32667603
复制相似问题