Rog*_*llo 8 c char integer-promotion bitwise-and isspace
我正在阅读一些实现简单解析器的代码。一个名为的函数将scan一行分解为标记。scan有一个静态变量bp,分配给要标记的行。在分配之后,空格被跳过。见下文。我不明白的是为什么代码对bp指向 with的字符进行按位和处理0xff,即, 的目的是* bp & 0xff什么?这怎么样:
while (isspace(* bp & 0xff))
++ bp;
Run Code Online (Sandbox Code Playgroud)
与此不同:
while (isspace(* bp))
++ bp;
Run Code Online (Sandbox Code Playgroud)
这是scan函数:
static enum tokens scan (const char * buf)
/* return token = next input symbol */
{ static const char * bp;
while (isspace(* bp & 0xff))
++ bp;
..
}
Run Code Online (Sandbox Code Playgroud)
来自 C 标准(7.4 字符处理 <ctype.h>)
1 头文件<ctype.h> 声明了几个对字符分类和映射有用的函数。198)在所有情况下,参数都是一个int,其值应表示为无符号字符或应等于宏EOF 的值。如果参数有任何其他值,则行为未定义。
在这次通话中
isspace(* bp)
Run Code Online (Sandbox Code Playgroud)
由于整数提升,*bp具有该类型的参数表达式char被转换为该类型int。
如果类型char表现为类型signed char并且表达式的*bp值为负,则类型的提升表达式的值int也将为负并且不能表示为类型的值 unsigned char。
这会导致未定义的行为。
在这次通话中
isspace(* bp & 0xff)
Run Code Online (Sandbox Code Playgroud)
由于按位运算符 &* bp & 0xff类型表达式的结果值int可以表示为类型的值unsigned char。
所以这是一个使用技巧,而不是编写更清晰的代码,例如
isspace( ( unsigned char )*bp )
Run Code Online (Sandbox Code Playgroud)
该函数isspace的实现方式通常是将其类型的参数int 用作具有 256 个值(从 0 到 255)的表中的索引。如果该类型的参数的int值大于最大值 255 或负值(并且不等于宏 EOF 的值),则函数的行为未定义。