GCC 4.5.0同样不改变X。
答案在于预处理器如何解释预处理标记以及“最大匹配”规则。 “最大匹配”规则是决定将“x+++++y”视为“x ++ ++ + y”(因而是错误的),而不是视为合法的“x ++ + ++ y”的规则。
问题是为什么预处理器会将“1e-X”解释为一个单独的预处理标记。显然,它将把“1e-10”视为单个标记。除非“1e-”后面跟随数字,否则它通过预处理器后就不存在有效的解释了。所以,我猜测预处理器将“1e-X”视为单个标记(实际上是错误的)。但我没有分析标准中的正确条款来确定是否需要这么做。但标准中“预处理数”或“pp-number”的定义(见下文)与整数或浮点常量的定义略有不同,并允许许多作为整数或浮点常量无效的“pp-number”。
如果有帮助的话,“cc-E-v soq.c”的Sun C编译器的输出结果如下:
int main()
{
"soq.c", line 4: invalid input token: 1e-X
double a = 1e-X ;
return 0;
}
cc: acomp failed for soq.c
所以,至少有一个C编译器在预处理器中拒绝该代码 - 可能是因为GCC预处理器有点松散(我尝试使用gcc -Wall -pedantic -std=c89 -Wextra -E soq.c
来引起它的抱怨,但它没有发出任何声音)。而在宏和“1e-XXX”符号表示法中使用3个X表明,所有三个X都被GCC和Sun C编译器消耗了。
C标准定义的预处理数字
从C标准 - ISO/IEC 9899:1999 §6.4.8预处理数字:
pp-number:
digit
. digit
pp-number digit
pp-number identifier-nondigit
pp-number e sign
pp-number E sign
pp-number p sign
pp-number P sign
pp-number .
鉴于此,'1e-X' 是一个有效的 'pp-number',因此 X 不是单独的标记('1e-XXX' 中的 'XXX' 也不是单独的标记)。因此,预处理器无法扩展 X;它不是可扩展的单独标记。