【问题标题】:Why doesn't "0xe+1" compile?为什么“0xe+1”不能编译?
【发布时间】:2018-03-28 20:22:17
【问题描述】:

看这段代码sn-p:

int a = 0xe+1;

Clang、gcc、icc 不要编译这个:

t.cpp:1:12: error: invalid suffix '+' on integer constant

MSVC 成功编译。

哪个编译器是正确的?如果 clang 和 gcc 都是正确的,为什么会这样?

注意:如果我在+ 之前添加一个空格,则代码会编译。如果我将0xe 更改为0xf,它也会编译。也许这与指数符号有关(例如1.2e+3)?

【问题讨论】:

  • 如果你的意思是0xe + 1,我相信你必须在+之前放一个空格。
  • @user2357112 这是 OP 可能想要的,但这不是编译器实际解析它的方式
  • @RemyLebeau 但十六进制浮点文字的指数表示法是 p,而不是 e
  • @Justin:看起来预处理编号的东西回答了它:预处理器标记化规则有点奇怪,与正常语法不太一致。
  • This note 似乎很相关。

标签: c++ syntax integer language-lawyer literals


【解决方案1】:

0xe+1 被视为单个 "preprocessing number" preprocessing token。这个标记化规则与普通语法中数字文字的定义不太一致;预处理数定义为

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 p sign
    pp-number P sign
    pp-number .

如果标记化规则基于数字文字定义而不是更简单的“预处理数字”定义,则您的表达式将被标记为 0xe + 1,但由于规则不匹配,您会得到一个 @987654326 @token,它不是一个有效的文字。

【讨论】:

  • 部分提到:预处理数字标记词法包括所有整数文字标记和所有浮动文字标记。和0xe是一个有效的整数标记,那么为什么编译器接受11+1和不是 0xe+1。
  • @Jean-BaptisteYunès:无法将11+1 解释为单个预处理数字; + 只能跟在预处理号码中的 eEpP
  • 哦,我明白了!这意味着 pp-number 定义涵盖了整数和浮点文字标记,但比有效文字更灵活并且更容易接受......我的问题是给定的 pp-number 定义不接受 0x 作为前缀;我错过了什么吗?当然是标识符-非数字推导!这个pp-number的定义非常非常奇怪……
  • @贾斯汀:为什么?解析(仅解析,无需计算值)整数/浮点数既简单又快速。我们可以有一个单独的 pp-integer 和 pp-float。当然,它并没有带来太多好处,但目前的行为很奇怪。大概标准已经定义了如何解析整数或浮点数,所以预处理器可以使用相同的定义,所以最终标准会简单一点(不需要pp-number)。
  • 这种行为通常被称为“最大咀嚼”(尽管“贪婪的词法分析”会更清楚 IMO)。另见this answer
猜你喜欢
  • 1970-01-01
  • 2011-06-25
  • 1970-01-01
  • 2011-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多