【问题标题】:Invalid character stream macros无效的字符流宏
【发布时间】:2011-12-08 07:41:36
【问题描述】:

以下预处理宏:

#define _VARIANT_BOOL /##/

实际上是无效的C;粗略地说,原因是预处理器被定义为处理令牌流,而上面假设它处理字符流。

另一方面,不幸的是,上述情况实际上发生在 Microsoft 头文件中,所以无论如何我都必须处理它。 (我正在研究预处理器实现。)

人们在野外遇到了哪些其他情况,无论是遗留代码,只要该代码可能仍在使用中,预处理器宏实际上是无效的,但仍然可以工作,因为它们是在编译器下编写的使用面向字符的预处理器实现?

(基本原理:如果我编写了一个适当的、符合标准的、面向令牌的正确干净的实现,我会尝试提前了解我将要破解多少特殊情况。)

【问题讨论】:

  • 为什么一定要处理呢?仅仅因为微软有一个非标准的预处理器和利用它的非标准头文件,并不意味着你需要处理它。
  • 嗯,目的是创建可以使用现有代码做有用事情的工具。无法读取 Microsoft 头文件的工具,即使它们在参考标准方面具有道德制高点,也不会那么有用。
  • 在这种情况下,我认为您的问题没有明确的答案。您需要支持的内容完全取决于您的目标市场。如果您正在编写符合标准的预处理器,那是一回事,否则您必须支持的扩展取决于您打算在什么环境中使用您的产品,这完全取决于您(或完全开放式)。
  • 我的目标是尽可能接近“任何环境中仍在使用的任何 C 代码”。
  • “任何环境中仍在使用的任何 C 代码”。你一定是在开玩笑吧?这只是大量的代码,您永远无法访问其中的 99.99%,而剩下的部分只有极少数项目会考虑使用带有新预处理器的新工具。

标签: macros c-preprocessor string-concatenation stringification


【解决方案1】:

标准的相关部分(§6.10.3.3 The ## operator) 说:

如果结果不是有效的预处理标记,则行为未定义。

这意味着您的预处理器可以做任何它喜欢的事情并且仍然符合标准,包括模拟常见行为。

我认为您仍然可以拥有“基于令牌”的实现并支持此行为,方法是指定当## 运算符的结果不是有效的预处理令牌时,结果是两个操作数令牌不变。您可能还希望让您的预处理器发出有关无效代码的警告。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多