【问题标题】:C++ implemented in plain C [duplicate]用纯 C 实现的 C++ [重复]
【发布时间】:2013-04-12 11:57:17
【问题描述】:

我曾多次阅读过早期的 C++ 编译器在编译前将第一个 C++ 代码翻译成纯 C(或者可能需要第三方 C 编译器)。

玩弄语法/语言/编译领域,我很想知道 C++ 是如何用纯 C 实现的,尤其是实现类继承和 [虚拟] 方法调用的一种方法。

你能告诉我这样一个现在仍然可用的编译器吗?

我知道可以使用结构和函数指针在纯 C 中模拟/模拟 OO 代码,但我希望看到 C++ 语言在 C 中的实际实现。

【问题讨论】:

  • 请记住,即使您找到它,它也不会是我们所知道的 C++,而是更简单的东西。我怀疑它做了一些事情,比如在所有函数上添加一个额外的参数,即帧指针。或者为这些东西保留一个全局变量。
  • 明确一点,C++ 语言在 C 中的实际实现,是指用 C 编写的 C++ 编译器,而不是可以将 C++ 翻译成 C 的工具,对吗?
  • 如何打开一些库文件,看看代码是如何完成的......
  • @NPE:是的,我有兴趣看到生成纯 C 代码的 C++ 编译器。不确定翻译人员是否会生成类似的代码或一些技巧来模拟 C++。

标签: c++ c compiler-construction implementation


【解决方案1】:

你可以试试cfront。您可以下载旧版本here。但它只支持非常有限的 C++ 子集。 有些功能比如异常不能用这种方式实现。

更新: 正如 Maxim Yegorushkin 所指出的,可以使用 setjmp/longjmp 实现异常。但是,如果我没记错的话,异常不能作为 C++ 中的库来实现。它们必须是核心语言的一部分。

【讨论】:

  • 异常无法实现不正确。早期的实现使用setjmp/longjmp 来实现异常。此方法在寻找异常处理程序时展开堆栈。现代编译器首先搜索异常处理程序,如果只找到一个,它们就会展开。这就是 C++ 标准说堆栈是否在未处理的异常上展开取决于实现的原因。显然,新行为对用户来说更方便,因为当您查看核心转储时对象尚未被销毁。
【解决方案2】:

如果您只想了解如何将 C++ 翻译成 C 语言,那么您可以使用多种选择,C++ FAQ 中有一个部分涵盖了这个here。它涵盖了我所见过的所有主要选项,并且应该在有新选项可用时进行更新。

【讨论】:

    【解决方案3】:

    Comeau compiler 以这种方式工作。在鼎盛时期,每个人都在称赞它的标准合规性,并使用 Comeau 在线测试代码的 sn-ps,但很少有人使用它来构建生产代码。

    EDGE frontend 也可以这样工作。我听说 Intel C++ 编译器和 Comeau 都使用它。

    【讨论】:

      【解决方案4】:

      第一个 Microsoft C++ 编译器与您描述的完全一样,我知道是因为我记得使用过它。根据我的记忆,我认为这是他们的 C 编译器的第 7 版。这应该是 1992 年左右(加/减 2 年)。

      更新:请参阅http://en.wikipedia.org/wiki/Visual_C%2B%2B,我所指的确实是在 1992 年发布的,名为“C/C++ 7.0”

      【讨论】:

        【解决方案5】:

        这就是 C++ 的原始实现(称为cfront)的工作原理。它是 C 编译器的前端。现在这并不常见,尽管 EDG 的 C++ 前端可以配置一个 C 后端,以便生成 C 代码。这在您运行新编译器时很有用,但在生产编译器中这是一个浪费的步骤,因此商业编译器通常直接进入目标平台的首选形式。而且您真的不想通过阅读生成的 C 代码来调试您的程序。我没有为 C++ 做过这个,但是当我在 Dinkumware 工作时,我们结合 EDG 开发的 Java 前端实现了 Java 核心库。 C 代码在逻辑上是结构化的,但它看起来很像 LISP:很多地狱愚蠢的括号。

        【讨论】:

          猜你喜欢
          • 2012-11-13
          • 2012-03-10
          • 2015-11-30
          • 1970-01-01
          • 1970-01-01
          • 2012-12-11
          • 2010-09-26
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多