条件包含:整数常量表达式是否有限?

Pav*_*kin 5 c language-lawyer constant-expression c-preprocessor preprocessor-directive

C11,6.10.1 有条件包含,约束,1(强调):

控制条件包含的表达式应为整数常量表达式

C11,6.6 常量表达式,6(强调):

整数常量表达式117)应具有整数类型,并且只能具有整数常量、枚举常量、字符sizeof常量、结果为整数常量的表达式、_Alignof表达式以及作为强制转换的直接操作数的浮点常量的操作数。

$ cat t333.c
#if (int)1.0
#endif

$ gcc t333.c -std=c11 -pedantic -c
t333.c:1:10: error: missing binary operator before token "1.0"
    1 | #if (int)1.0
Run Code Online (Sandbox Code Playgroud)

这里(int)1.0是整型常量表达式。它具有整数类型并具有操作数,该操作数是浮点常量,是强制转换的立即操作数。但是,每个gcc代码都是无效的。

这意味着 6.10 预处理指令中使用的“整数常量表达式”受到限制 [1]?标准中有明确规定吗?

[1] 例如,“除了sizeof结果为整数常量、_Alignof表达式和作为强制转换的直接操作数的浮点常量的表达式”

dbu*_*ush 8

您需要完整地查看 6.10.1p1:

\n
\n

控制条件包含的表达式应为整数常量表达式,但以下情况除外: 标识符(包括在词法上与关键字相同的标识符)按如下所述进行解释166),并​​且它可能包含\n以下形式的一元运算符表达式

\n
defined identifier\n
Run Code Online (Sandbox Code Playgroud)\n

或者

\n
defined ( identifier )\n
Run Code Online (Sandbox Code Playgroud)\n

如果标识符当前定义为宏名称(即,如果它是预定义的,或者它是预处理指令的主题,而没有具有#define相同#undef主题标识符的中间指令),则计算结果为 1,如果它不是。

\n
\n

其中脚注 166 指出:

\n
\n
    \n
  1. 因为控制常量表达式是在转换阶段 4 期间计算的,所以所有标识符要么是宏名称,要么不是宏名称\n\xe2\x80\x94,根本没有关键字、枚举常量等。
  2. \n
\n
\n

因此,预处理器不会将关键字int视为关键字,而是将其视为标识符,从而视为宏名称。这会导致语法无效并导致错误。

\n

这意味着指令中不允许使用涉及强制转换、sizeof或 的整数常量表达式。_Alignof#if

\n