预处理器运算符"defined"的优先级?

The precedence of preprocessor operator "defined"?

我正在研究一个 c 预处理器并且发现,由于 "defined" 是一个预处理器专用运算符,它的优先级从未在其他 c 运算符中列出。因为它是一元的和合乎逻辑的,所以我会把它放在第二层,但是...

有谁知道确切答案吗?

C 2018 6.10.1 1 说:

The expression that controls conditional inclusion shall be an integer constant expression except that… it may contain unary operator expressions of the form “defined identifier” or “defined ( identifier )”… [Note: The text in quotes here is offset display text in the original.]

短语“一元运算符表达式”指的是 6.5.3(“一元运算符”),6.5(“表达式”)的一个小节。因此,defined 的行为类似于任何其他一元运算符。

但是,注意操作数必须是标识符。它不能是大多数普通运算符接受的通用 unary-expressioncast-expression。正是那些 unary-expressioncast-expression 符号将更高优先级的运算符引入一元表达式的语法中。这意味着像 #if defined x++ 这样的东西是不允许的(甚至在考虑 ++ 是否可能出现在整数常量表达式中之前),所以没有任何其他选择。 “defined identifier”从不与标识符相邻的任何更高优先级运算符一起出现。

#if 指令紧跟常量表达式。任何 defined 运算符先被计算 ,然后再计算常量表达式的其余部分。

C 标准的第 6.10.1p4 节指出:

Prior to evaluation, macro invocations in the list of preprocessing tokens that will become the controlling constant expression are replaced (except for those macro names modified by the defined unary operator), just as in normal text. If the token defined is generated as a result of this replacement process or use of the defined unary operator does not match one of the two specified forms prior to macro replacement, the behavior is undefined. After all replacements due to macro expansion and the defined unary operator have been performed, all remaining identifiers
(including those lexically identical to keywords) are replaced with the pp-number 0 , and then each preprocessing token is converted into a token. The resulting tokens compose the controlling constant expression which is evaluated according to the rules of 6.6. ...

参考文献第 6.6 节规定了常量表达式的语义