【问题标题】:Unspecified evaluation order of stringize operatorsstringize 运算符的未指定评估顺序
【发布时间】:2014-01-17 00:29:48
【问题描述】:

一元运算符的解析优先级通常高于二元运算符,当从左到右扫描时,首先会找到前缀运算符。那么为什么 stringize (#) 运算符的求值顺序未针对连接 (##) 运算符指定呢?在 [cpp.stringize] §16.3.2 的上下文中,评估顺序是否意味着与优先级不同的东西?

(预处理器没有副作用,所以从技术上讲,它没有评估顺序之类的东西。)

考虑到任何替代方案都会将连接的结果字符串化,而不是论据本身?

是否有任何实现做一些有趣的事情,或者评估文本的顺序是否可以安全地删除并替换为“# 运算符的优先级高于## 运算符”?

此问题已交叉发布到标准讨论邮件列表,但请在此处回复。

注意:我计划起草一份正式的提案来修改这部分 C++ 规范,所以请分享你的知识!潜在的动机是使预处理器更具确定性。

【问题讨论】:

  • 首先,“优先级”和“求值顺序”是完全正交的概念……
  • @R.. 需要保留一粒盐,因为标准中使用的确切术语“评估顺序”在字面上下文中毫无意义。我欢迎任何关于规范这部分起源的启示,因为 AFAIK 没有历史预处理器曾经有副作用。

标签: c++ c-preprocessor operator-precedence stringification


【解决方案1】:

我希望看到另一个答案,但在@R 的评论之后,我倾向于认为标准的含义正是它所说的。由于没有副作用,评估顺序在预处理器中没有影响,因此不应指定。应指定### 的优先级和关联性,但从标准中省略。

associativityprecedence求值顺序 中的每一个都有相互排斥的含义,标准应该高于反驳它们。

编辑:我已经正式proposed 来解决这个问题。 (参见第 5.1 节。)

【讨论】:

  • '没有效果'绝对不是真的。显然,评估顺序在预处理器中有效。考虑#define e(a,b) # a ## b,如果a 粘在b 上然后字符串化,则行为是定义。如果 a 被字符串化 THEN 粘合到 b,则结果不是有效的预处理标记,并且行为是 undefined。我想大多数人都会同意这会产生严重的影响。
  • @Wiz 您指的是优先级,而不是评估顺序。无论如何,stringize 运算符的定义基本上阻止了粘贴“首先”发生。我现在已经编辑了答案,使其更加清晰。
  • 你是对的。但这让我相信,当它说 C11 §6.10.3.2 p3 The order of evaluation of # and ## operators is unspecified. 时,标准意味着优先级而不是顺序,因为宏评估本身(扩展)的顺序不会改变任何东西。但是优先级确实如此。顺便说一句,你从哪里得到 stringize 运算符不能首先发生的? (该示例恰好来自航空安全编码实践手册。)
  • @Wiz 你能给我那本书的参考吗?我正在编写一份正式的 ISO 提案来修改预处理器规范,这将是很好的 ammunition 证据,表明当前规范缺乏质量会产生实际后果。无法对连接结果进行字符串化,因为 stringize 运算符专门适用于以下宏参数。无法将a ## b 解释为宏参数。此外,如果 b 为空,或者在 C++11 中它形成 ud-string-literal,则结果标记 "a"b 格式正确的。
  • @Wiz Ping...您能提供航空编码手册的参考吗?即使它受到严重版权保护或以某种方式受到保护,引用和参考对我来说也是无价的。太多的工业指南奇怪地“封闭”了……
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-14
  • 1970-01-01
  • 2013-07-30
  • 1970-01-01
  • 2015-01-23
  • 2016-12-31
  • 1970-01-01
相关资源
最近更新 更多