在线许多来源(例如,)说,表达式仅是整数常数表达式。
以下都是整体常数的表达式,没有任何标识符:
#include <compare>
#if (1 <=> 2) > 0
#error 1 > 2
#endif
#if (([]{}()), 0)
#error 0
#endif
#if 1.2 < 0.0
#error 1.2 < 0.0
#endif
#if ""[0]
#error null terminator is true
#endif
#if *""
#error null terminator is true
#endif
但是它们无法与Clang或GCC进行编译,因此显然存在一些局限性。
#if
指令的语法在标准中的[cpp.pre]中给出:
if-group :
#
如果
constant-expression new-line group opt sub>
以前的所有表达式都符合恒定表达的语法。
稍后再说(在[cpp.cond]中):
1/
控制条件包含的表达式应为整体常数表达式,除非标识符(包括与关键字相同的标识符)如下所述
所述。
8/
在所有宏替换发生后,每个将成为控制表达式的预处理令牌(将成为控制表达式的预处理令牌列表中)的每个预处理令牌应为令牌的词汇形式。
>
所有的预处理令牌似乎都以[lex.token]的形式:
令牌:
标识符
关键字
文字
操作员 - 或函数
&lt; =&gt;
,&gt;
,,
,,] , {
,},
(
,)
,*
都是操作员 - 或 - 函数
1
, 2
, 0
, 1.2
,<代码> 0.0 ,<代码>“” 都是文字
,那么标准的哪一部分排除了这些形式的表达式?允许哪些积分常数表达式?
Many sources online (for example, https://en.cppreference.com/w/cpp/preprocessor/conditional#Condition_evaluation) say that the expression need only be an integer constant expression.
The following are all integral constant expressions without any identifiers in them:
#include <compare>
#if (1 <=> 2) > 0
#error 1 > 2
#endif
#if (([]{}()), 0)
#error 0
#endif
#if 1.2 < 0.0
#error 1.2 < 0.0
#endif
#if ""[0]
#error null terminator is true
#endif
#if *""
#error null terminator is true
#endif
Yet they fail to compile with clang or gcc, so there obviously are some limitations.
The grammar for the #if
directive is given in [cpp.pre] in the standard as:
if-group:
#
if
constant-expression new-line groupopt
All of the previous expressions fit the grammar of constant-expression.
It goes on later to say (in [cpp.cond]):
1/
The expression that controls conditional inclusion shall be an integral constant expression except that identifiers (including those lexically identical to keywords) are interpreted as described below
8/
Each preprocessing token that remains (in the list of preprocessing tokens that will become the controlling expression) after all macro replacements have occurred shall be in the lexical form of a token.
All of the preprocessing tokens seem to be in the form of [lex.token]:
token:
identifier
keyword
literal
operator-or-punctuator
<=>
, >
, [
, ]
, {
, },
(
, )
, *
are all an operator-or-punctuator
1
, 2
, 0
, 1.2
, 0.0
, ""
are all literals
So what part of the standard rules out these forms of expressions? And what subset of integral constant expressions are allowed?
发布评论
评论(1)
我认为所有这些示例均旨在不明显,尽管您证明当前的标准措辞没有这种影响。
这似乎被跟踪为Active 。提出的分辨率将取消字符串文字,浮点文字,以及
&lt; =&gt;
从#if
条件中。 (尽管&lt; =&gt;
在编写了问题描述后已添加到该语言中。)我想它也是要禁止lambdas,但这可能不被提议的措辞覆盖。I think that all of these examples are intended to be ill-formed, although as you demonstrate the current standard wording doesn't have that effect.
This seems to be tracked as active CWG issue 1436. The proposed resolution would disqualify string literals, floating point literals and also
<=>
from#if
conditions. (Although<=>
was added to the language after the issue description was written.) I suppose it is also meant to disallow lambdas, but that may not be covered by the proposed wording.