【问题标题】:Disambiguating id-expression and type-id in sizeof expressions在 sizeof 表达式中消除 id-expression 和 type-id 的歧义
【发布时间】:2021-05-24 22:39:33
【问题描述】:

我无法弄清楚标准如何消除 sizeof expressions 的歧义,这可能是(除其他外):

sizeof 一元表达式
sizeof ( type-id )

例如,我想知道标准如何区分

一元表达式
sizeof
一元表达式 ... 主表达式
(
表达式 ... 主表达式, id-expression, unqualified-id
identifier
)

一元表达式
sizeof
(
type-id ... simple-type-specifier, type-name, typedef-name
identifier
)

其他可能是标识符的类型名称也会出现类似的歧义,我想了解这如何映射到标准。

[编辑]
澄清一下:我能够很好地根据它们的声明方式(typedef、类等)来区分 type-name 的标识符 - 但是我目前看不到 id -expression(或其包含的 unqualified-id)在另一个解析可能匹配 type-id 时消除歧义。正如在 cmets 中提出的那样,针对特定情况存在各种规则来消除表达式与类型 ID 的歧义,但我还没有看到它们如何扩展到这种特定情况(除非您推断并假设类型 ID 总是胜过表达式,这已被建议作为对 cme​​ts 中消歧规则的可能解读)。
[end edit]

我的想法是寻找关于什么标识符可以是 id-expression 的任何约束,但我找不到任何具体的东西,我能看到的最接近约束的是非常无用的措辞在5.1.1/8

标识符是一个 id 表达式,前提是它已被适当声明(第 7 条 [dcl.dcl])。

查看提到的部分,我找不到参考的含义,在网上我只找到了this question,但答案并没有详细说明

该短语的目的是禁止在表达式中使用未声明的标识符。

所以要么解决的方式与我想的不同,要么“适当地宣布”我失踪了。

PS:使用 C++14 标准没有什么特别的原因,它正是我当时一直在使用的,对于新标准的答案也一样好。自己检查新标准中提到的部分似乎没有任何明显的澄清。

【问题讨论】:

  • @T.C.我看不出这将如何解决标识符的解释,因为不涉及函数样式转换;两个语法规则都严格简化为一个标识符。
  • 它首先讨论了函数样式转换,但它制定的消歧规则更笼统:任何可以是 type-id 的东西都是 type-id。
  • @T.C.好的,我现在知道您是如何阅读它的,但是如果打算建立一般裁决,这是非常奇怪的措辞。在它的段落中,它描述了一个模棱两可的地方,然后说“[这个模棱两可的]解决方案是……”,所以期望读者假设一个普遍的裁决是有问题的。感谢您指出这一点!
  • 那...实际上并不是如何消除 template-argument 的歧义:timsong-cpp.github.io/cppwp/n4861/temp.arg#2

标签: c++ language-lawyer


【解决方案1】:

这是lexer hack标识符unqualified-idtype-name还是模板名称 是根据已处理的声明 或依赖上下文中的typenametemplate 解析器指南确定的。这是区分 A * b; 解释为指针的 simple-declaration 或丢弃 a 结果的 expression-statement 的唯一方法乘法。

该标准对此非常含糊:它仅提及在 [class.pre]/1 之类的声明中出现的标识符的解释:

它的名字在它的范围内变成了一个类名([class.name])。

[temp.param]/3:

type-parameteridentifier 不跟在省略号之后,将其 identifier 定义为 typedef-name(如果声明时没有 template)或 template-name(如果声明时使用 template)在模板声明的范围内。

[temp.local]/1,它也依赖于语法:

注入的类名可以用作模板名类型名

和 [temp.names]/3,它是注释的一部分,因为规范文本指定了 < 的解释:

[注意 1:如果名称是 标识符,则它会被解释为 模板名称。 […] — 尾注]

【讨论】:

  • 我很清楚这一点,我正在寻找标准如何根据标识符的知识要求选择哪个解析(如果这就是它消除这种语法歧义的方式)
  • 为了让这更“有趣”,模板模板参数使用 id-expression 产生式。有一天“声明以及如何解析它们”?
  • @Zarat:它几乎没有,这就是为什么这不是我的第一个想法——但我添加了一些引用来证明微薄的规范。
  • 不幸的是,引用的部分似乎都与问题无关,这是关于 id-expression(或 unqualified-id)冲突与所有其他人 - 或者我仍然错过了你的观点。我可以很容易地将 type-nametypedef-name 而不是 class-name 等消除歧义,但我错过了它的推理方式不允许在 id-expressions 中使用它们(更具体地说,它允许在那里使用它们)
  • @Zarat:如果一个名字(比如说)“变成了一个class-name”,那么它就没有资格被解释为一个unqualified-id i>(没有来自 class-name 的产生),不是吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-11
  • 1970-01-01
  • 1970-01-01
  • 2012-09-28
  • 2016-09-26
  • 1970-01-01
相关资源
最近更新 更多