7

以下代码在 GCC 和 Clang 中编译:

long double operator""_a(long double);     
auto x = 0e1_a+0; // OK 

但不是这个(替换_a_e):

long double operator""_e(long double);
auto y = 0e1_e+0; // Error: unable to find numeric literal operator 'operator""_e+0'

OTOH,此代码编译:

auto z = 0e1_e +0; // OK

这是怎么回事?

(这个问题的灵感来自这个 GCC 错误报告。)

4

1 回答 1

14

最大的咀嚼再次来袭。

[lex.pptoken]/p3:

如果输入流已被解析为预处理标记,直到给定字符:

  • [此处不相关的两个例外]
  • 否则,下一个预处理标记是可以构成预处理标记的最长字符序列,即使这会导致进一步的词法分析失败,除非 标头名称(2.8) 仅在#include指令 (16.2) 中形成。

问题在于0e1_e+0,与 不同0e1_a+0,它是一个有效的预处理数字([lex.ppnumber]):

pp-number:
    digit
    . digit
    pp-number digit
    pp-number identifier-nondigit
    pp-number ’ digit
    pp-number ’ nondigit
    pp-number e sign
    pp-number E sign
    pp-number .

结果,0e1_e+0被解析为单个pp-number预处理令牌,然后由于无法转换为有效令牌(原因很明显)而在稍后爆炸。

0e1_a+0另一方面,被解析为三个标记,0e1_a+0,一切都很好。

于 2015-11-12T11:18:33.443 回答