6

在 C++11 中,当表单的预处理指令...

#if expr

...遇到,expr被评估为 a constant-expression,如 中所述16.1 [cpp.cond]

这是在宏替换 on 之后完成的expr,它的标识符(和关键字)被 0 替换,它preprocessing-tokens被转换为tokensdefined运算符被评估,等等。

我的问题是当其中一个标记expr是 a时会发生什么user-defined-literal

用户定义的文字就像函数调用,但函数调用不能在expr(我认为)中发生,这是标识符替换的副作用。但是从技术上讲user-defined-literals可以生存。

我怀疑这是一个错误,但我不太明白如何从标准中得出结论?

[cpp]也许只是忽略了在第 16 条上添加用户定义的文字的(迂腐的)影响?

还是我错过了什么?

更新:

举个例子来说明:

这个预处理是什么:

#if 123_foo + 5.5 > 100
bar
#else
baz
#endif

bar 或 baz 还是错误?

GCC 4.7 报告:

test.cpp:1:5: error: user-defined literal in preprocessor expression

所以它认为这是一个错误。参考标准可以证明这是合理的吗?或者这只是“隐含的”?

4

2 回答 2

3

在 C++11 中,当#if expr ...遇到 ... 形式的预处理指令时, expr将评估为 a constant-expression,如16.1 [cpp.cond].

这是在宏替换 on 之后完成的expr,它的标识符(和关键字)被替换为0,它preprocessing-tokens被转换为tokensdefined运算符被评估,等等。

我的问题是当其中一个tokensexpra 时会发生什么user-defined-literal

该程序格式不正确。

16.1/1我的论点的核心是从脚注中的观察中收集的147,在翻译阶段 4 中identifiers除了宏名称之外别无他物。

争论:

根据2.14.8 [lex.ext]/2

Auser-defined-literal被视为对 aliteral operator 或的调用literal operator template (13.5.8)

因此,即使在16.1/4. (其他尝试,例如使用constexpr函数,将被所有非宏替换为identifiers. 0)

由于这发生在翻译阶段 4,还没有定义甚至声明的函数;尝试查找literal-operator-idmust 失败(参见脚注 147 中16.1/1的类似论点)。

从稍微不同的角度来看,5.19/2我们发现:

Aconditional-expression是 a core constant expression,除非它涉及以下之一作为潜在评估的子表达式 (3.2) [...]:

  • [...]
  • 对文字类或 constexpr 函数的 constexpr 构造函数以外的函数的调用;
  • 调用未定义的 constexpr 函数或未定义的 constexpr 构造函数 [...];

由此,在 auser-defined literal中使用 aconstant expression需要定义constexpr literal operator,这在翻译阶段 4 中也不能使用。

gcc 拒绝这一点是正确的。

于 2013-02-17T12:03:12.987 回答
0

在 C++11 中,当#ifdef expr遇到形式的预处理指令时,将expr被评估为常量表达式,如 16.1 所述。这是在 expr 上的宏替换之后完成的,它的标识符(和关键字)被替换为 0,它的预处理标记被转换为标记,定义的运算符被评估,等等。

不!

#ifdef#ifndefdefined的参数被评估。例如,假设我从不#define使用预处理器符号SYMBOL_THAT_IS_NEVER_DEFINED。这是完全有效的:

#ifdef SYMBOL_THAT_IS_NEVER_DEFINED
code
#endif

扩展未定义符号的符号是非法的。假设SYMBOL_THAT_IS_NEVER_DEFINED尚未定义,这是非法的:

#if SYMBOL_THAT_IS_NEVER_DEFINED
code
#endif

类似于在解除引用之前检查指针是否为非空,在使用之前检查符号是否合法:

#if (defined SYMBOL_THAT_MIGHT_BE_DEFINED) && SYMBOL_THAT_MIGHT_BE_DEFINED
code
#endif
于 2013-02-16T23:13:30.063 回答