条件包含:整型常量表达式受限?

Conditional inclusion: integer constant expression is limited?

C11,6.10.1 条件包含,约束,1(添加了重点):

The expression that controls conditional inclusion shall be an integer constant expression

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

An integer constant expression117) shall have integer type and shall only have operands that are integer constants, enumeration constants, character constants, sizeof expressions whose results are integer constants, _Alignof expressions, and floating constants that are the immediate operands of casts.

$ 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

此处(int)1.0中的整型常量表达式。它具有整数类型并具有操作数,该操作数是浮点常量,是强制转换的直接操作数。但是,根据 gcc 代码无效。

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

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

您需要完整查看 6.10.1p1:

The expression that controls conditional inclusion shall be an integer constant expression except that: identifiers (including those lexically identical to keywords) are interpreted as described below;166), and it may contain unary operator expressions of the form

defined identifier

or

defined ( identifier )

which evaluate to 1 if the identifier is currently defined as a macro name (that is, if it is predefined or if it has been the subject of a #define preprocessing directive without an intervening #undef directive with the same subject identifier), 0 if it is not.

脚注 166 指出:

  1. Because the controlling constant expression is evaluated during translation phase 4, all identifiers either are or are not macro names — there simply are no keywords, enumeration constants, etc.

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

这意味着在 #if 指令中不允许涉及转换、sizeof_Alignof 的整数常量表达式。