51

我有一些 C++ 代码。在代码中定义了许多类,它们的成员函数、构造函数、这些类的析构函数、少量模板类和大量 C++ 内容。现在我需要将源代码转换为纯 C 代码。

我有以下问题:

  1. 是否有任何工具可以将 C++ 代码和头文件转换为 C 代码?

  2. 我是否必须完全重写代码(我将不得不删除构造函数、析构函数并将该代码移动到一些函数init()deinit();将类更改为结构,使现有的成员函数作为那些新定义的结构中的函数指针,然后调用那些使用函数指针等的函数)?

  3. 如果我必须自己手动转换,在从 C++ 到 C 的转换时,我需要注意哪些 C++ 特定的代码数据结构/语义?

4

6 回答 6

31

确实有这么一个工具,Comeau 的 C++ 编译器。. 它将生成您无法手动维护的 C 代码,但这没问题。您将维护 C++ 代码,并即时转换为 C。

于 2009-04-10T10:37:45.263 回答
23

http://llvm.org/docs/FAQ.html#translatecxx

它处理一些代码,但对于更复杂的实现会失败,因为它还没有完全更新一些现代 C++ 约定。因此,请尝试经常编译您的代码,直到您对允许的内容有所了解。

对于 9.0.1 版,命令行中的使用语法如下:

clang -c CPPtoC.cpp -o CPPtoC.bc -emit-llvm
clang -march=c  CPPtoC.bc -o CPPtoC.c

对于旧版本(不确定转换版本),请使用以下语法:

llvm-g++ -c CPPtoC.cpp -o CPPtoC.bc -emit-llvm
llc -march=c  CPPtoC.bc -o CPPtoC.c

请注意,它创建了 C 的 GNU 风格,而不是真正的 ANSI C。在您对代码投入过多之前,您需要测试它是否对您有用。例如,一些嵌入式系统只接受 ANSI C。

另请注意,它会生成功能但相当不可读的代码。我建议评论和维护您的 C++ 代码,而不用担心最终的 C 代码。

编辑:虽然此功能的官方支持已被删除,但用户仍然可以使用Julia 语言开发人员非官方支持来实现上述功能。

于 2009-04-10T10:48:32.727 回答
5

也许好的 ol' cfront会做?

于 2012-10-03T23:05:29.643 回答
5

虽然您可以在 C 中执行 OO(例如,通过向theType *this方法添加第一个参数,并手动处理诸如多态的 vtable 之类的东西),但作为设计,这永远不会特别令人满意,而且看起来很丑陋(即使有一些预处理器黑客)。

我建议至少看一个重新设计来比较这将如何工作。

总体而言,很大程度上取决于关键问题的答案:如果您有工作的 C++ 代码,为什么要使用 C?

于 2009-04-10T10:38:13.827 回答
4

编译器由两个主要块组成:“前端”和“后端”。编译器的前端分析源代码并构建所述源代码的某种形式的“中间表示”,这比源代码更容易通过机器算法分析(即,源代码例如 C++ 旨在帮助人类程序员编写代码,中间形式旨在帮助简化分析所述中间形式的算法)。编译器的后端采用中间形式,然后将其转换为“目标语言”。

现在,通用编译器的目标语言是各种处理器的汇编语言,但没有什么可以禁止编译器后端以其他语言生成代码,只要所述目标语言(至少)与通用 CPU 汇编程序。

现在,正如您可能想象的那样,C 绝对与 CPU 的汇编程序一样灵活,因此从技术角度实现 C++ 到 C 编译器确实没有问题。

所以你有:C++ ---frontEnd---> someIntermediaryForm ---backEnd---> C

你可能想看看这些人:http ://www.edg.com/index.php?location=c_frontend (上面的链接只是说明可以做什么,他们以数万美元的价格许可他们的前端)

PS 据我所知,GNU 没有这样的 C++ 到 C 编译器,这完全打败了我(如果我是对的)。因为 C 语言相当小,而且它的内部机制相当简陋,所以 C 编译器需要大约一个人年的工作(我可以第一手告诉你,因为我可能几年前自己编写了这样一个编译器,它会产生一个 [ virtual] 堆栈机器中间代码),并且能够拥有一个维护的、最新的 C++ 编译器,而只需要编写一次 C 编译器将是一件很棒的事情......

于 2013-01-10T16:35:36.233 回答
2

这是一个旧线程,但显然C++ Faq有一个部分 (存档 2013 版本)。如果联系作者,这显然会更新,所以从长远来看,这可能会更新,但这是当前版本:

取决于你的意思。如果您的意思是,是否可以将 C++ 转换为可读且可维护的 C 代码?那么抱歉,答案是否定的——C++ 特性不直接映射到 C,而且生成的 C 代码不适合人类遵循。相反,如果您的意思是,是否存在将 C++ 转换为 C 的编译器,以便在没有 C++ 编译器的平台上进行编译?那么你很幸运——继续阅读。

将 C++ 编译为 C 的编译器会对程序进行完整的语法和语义检查,并且恰好使用 C 代码作为生成目标代码的一种方式。这样的编译器不仅仅是某种花哨的宏处理器。(请不要给我发电子邮件声称这些是预处理器——它们不是——它们是完整的编译器。)可以通过转换为 C 来实现 ISO 标准 C++ 的所有功能,并且除了异常处理之外,它通常会导致在目标代码中的效率与传统 C++ 编译器生成的代码相当。

以下是一些执行 C 编译的产品:

  • Comeau Computing提供了一个基于Edison Design Group 前端的编译器,用于输出 C 代码。
  • LLVM是一个可下载的编译器,它发出 C 代码。另请参阅此处此处。这是通过 LLVM 进行 C++ 到 C 转换的示例
  • Cfront是 C++ 的原始实现,由 Bjarne Stroustrup 和 AT&T 的其他人完成,它生成 C 代码。但是它有两个问题:自 90 年代中期开始经历所有权变更的迷宫以来,很难获得许可证,同时开发停止,因此它没有得到错误修复,也不支持任何较新的语言特性(例如,异常、命名空间、RTTI、成员模板)。

  • 与流行的神话相反,在撰写本文时,还没有将 C++ 转换为 C 的 g++ 版本。这样的事情似乎是可行的,但我不知道是否有人实际做过(目前)。

请注意,您通常需要指定目标平台的 CPU、操作系统和 C 编译器,以便生成的 C 代码专门针对该平台。这意味着: (a) 您可能无法获取为平台 X 生成的 C 代码并在平台 Y 上编译它;(b) 自己进行翻译会很困难——使用其中一种工具可能会更便宜/更安全。

再说一次:不要给我发电子邮件说这些只是预处理器——它们不是——它们是编译器。

于 2013-03-12T18:37:54.180 回答