【问题标题】:How to convert C++ Code to C [closed]如何将 C++ 代码转换为 C [关闭]
【发布时间】:2010-10-18 17:53:39
【问题描述】:

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

我有以下问题:

  1. 有没有工具可以将C++代码和头文件转换成C代码?

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

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

【问题讨论】:

    标签: c++ c code-translation


    【解决方案1】:

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

    【讨论】:

    • @MSalters:感谢有关 Comeaus 编译器的指针。但遗憾的是,这并没有达到我的目的,因为无法获得 Comeaus 编译器中间格式 c 代码,即使我们以某种方式获得它也无法被普通的 ANSI-C 编译器编译。
    • 如果您的代码不使用异常和模板,您可能有机会获得 cfront 的旧副本来处理您的代码。但正如 MSalters 所说,它会很丑:-)
    • 它也必须不使用标准库功能
    • @Pacerier:这绝不是完美的。它产生可怕的不可读、不可维护的 C 代码。但是,是的,与几年前的 C++ 相比,C 实际上已经失去了任何优势。微软甚至不再关心 C。
    • @MSalters,它根本不可读,不是吗?就像机器代码不可读根本不重要一样。您用 C++ 编写代码,然后当我们需要部署时,我们将 C++ 转换为 C,然后进行部署。然后你继续编辑 C++ 代码,我们重复一遍。那么C语言就没有优势了吗?
    【解决方案2】:

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

    我建议至少重新设计一下,以比较结果如何。

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

    【讨论】:

    • 作者的理由显然是具体的,但理由确实存在。有时,特定平台上不存在 c++ 编译器,或者可能由于某种原因不可用。它也是一个非常优秀的学习工具。
    【解决方案3】:

    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
    

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

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

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

    【讨论】:

    • 我尝试使用 LLVM 将 hello_world.cpp 转换为 C 文件。生成的 C 代码与机器代码一样丑陋。预处理器的包含都消失了。
    • @MikimotoH,它看起来是这样,因为它不是语法到语法源翻译。它确实是一个可以输出到 c 的编译器,这意味着您仍然依赖于任何链接的 C++ 库。它确实最适合用于调试或作为查看材料。顺便说一句:它可能很丑,但相信我它比机器代码更好,你至少可以从中学习。从clang c++到c,你可以比任何反汇编学习得更好。
    • 如果有人需要将一些 C++ 代码编译到一些只有 C 编译器的奇怪机器/微控制器上,这似乎仍然是一个很好的解决方案。
    • @Cray:我已经尝试过了,遗憾的是 LLVM c 后端不会转换为纯 ANSI C 标准代码,而是 GNU C 编译器代码。这排除了很多仅 ANSI C 编译器的芯片。
    • 自 v3.1 起已移除 C 后端功能。 “它有很多问题,以至于无法编译任何重要的程序。”
    【解决方案4】:

    也许不错的cfront 可以吗?

    【讨论】:

    • 据我所知,cfront已经很久没有维护了,不太可能处理现代C++代码。
    【解决方案5】:

    编译器由两个主要部分组成:“前端”和“后端”。 编译器的前端分析源代码并构建所述源代码的某种形式的“中间表示”,这比源代码更容易通过机器算法分析(即,源代码例如 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 编译器将是一件很棒的事情......

    【讨论】:

    • 通用编译器的目标语言是各种处理器的汇编语言(或机器码??)
    • EDG 不幸放弃了他们的 C 前端
    【解决方案6】:

    这是一个旧线程,但显然C++ Faq 有一个section (Archived 2013 version)。如果与作者联系,这显然会得到更新,因此从长远来看,这可能会更新,但这是当前版本:

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

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

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

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

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

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

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

    【讨论】:

    • 这没有提供问题的答案。
    • 链接似乎已损坏。
    • Comeau Computing 现在似乎完全死了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-01
    • 2023-03-09
    • 2012-05-14
    相关资源
    最近更新 更多