How to convert C++ Code to C [closed]
Asked Answered
A

6

54

I have some C++ code. In the code there are many classes defined, their member functions, constructors, destructors for those classes, few template classes and lots of C++ stuff. Now I need to convert the source to plain C code.

I the have following questions:

  1. Is there any tool to convert C++ code and header files to C code?

  2. Will I have to do total rewrite of the code (I will have to remove the constructors,destructors and move that code into some init(), deinit() functions; change classes to structures, make existing member functions as function pointers in those newly defined structures and then invoke those functions using function pointers etc..)?

  3. If I have to convert it manually myself, what C++ specific code-data constructs/semantics do I need to pay attention to while doing the conversion from C++ to C?

Argentous answered 10/4, 2009 at 10:30 Comment(0)
A
33

There is indeed such a tool, Comeau's C++ compiler. . It will generate C code which you can't manually maintain, but that's no problem. You'll maintain the C++ code, and just convert to C on the fly.

Avail answered 10/4, 2009 at 10:37 Comment(6)
@MSalters: Thanks for the pointer about Comeaus compiler. But sadly that doesnt serve my purpose, as comeaus compiler intermediate format c code is not possible to obtain, and even if we obtain somehow its not compilable by normal ANSI-C compilers.Argentous
If your code does not use exceptions and templates you might have a chance to get an old copy of cfront to work on your code. But as MSalters said it's going to be ugly :-)Debroahdebs
it would also have to use no standard library functionalityDyann
If C++ can be translated into C perfectly, then doesn't that effectively kill point 1 and point 2 of programmers.stackexchange.com/a/113316/24257 ? Doesn't that mean that C has no longer any objective advantage over C++ any more?Relique
@Pacerier: It's anything but perfect. It produces horribly unreadable, unmaintainable C code. But yes, C has effectively lost any advantage over C++ years ago. Microsoft doesn't even bother with C anymore.Avail
@MSalters, It doesn't at all matter that it's unreadable does it? Just like how it doesn't at all matter that machine code is unreadable. You code in C++, then when we need to deploy, we take the C++, convert it into C, and deploy. Then you continue to edit the C++ code and we repeat. So there's no longer any advantage in C is there?Relique
V
24

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

It handles some code, but will fail for more complex implementations as it hasn't been fully updated for some of the modern C++ conventions. So try compiling your code frequently until you get a feel for what's allowed.

Usage sytax from the command line is as follows for version 9.0.1:

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

For older versions (unsure of transition version), use the following syntax:

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

Note that it creates a GNU flavor of C and not true ANSI C. You will want to test that this is useful for you before you invest too heavily in your code. For example, some embedded systems only accept ANSI C.

Also note that it generates functional but fairly unreadable code. I recommend commenting and maintain your C++ code and not worrying about the final C code.

EDIT : although official support of this functionality was removed, but users can still use this unofficial support from Julia language devs, to achieve mentioned above functionality.

Vanessa answered 10/4, 2009 at 10:48 Comment(7)
@plan9assembler: Thanks for the pointer. I will check it out and let u know.Argentous
I have tried to convert hello_world.cpp to C file by using LLVM. The resulting C code is as ugly as machine code. The preprocessor's include's are all gone.Ballerina
@MikimotoH, it looks that way because its not a syntax to syntax source translation. Its really a compiler that can output to c, which means you still are dependent on any linked C++ libs. Its really best used for debugging, or as viewing material. BTW: ugly it may be, but believe me its better than machine code and you could at least learn from it. You can learn better from clang c++ to c, than any disassembly.Thierry
Still seems like a great solution, if somebody would ever need to compile some C++ code to some strange machine/microcontroller that only has C compilter.Microdont
@Cray: I've tried and sadly LLVM c backend does not convert to plain ANSI C standard code, but GNU C compiler code instead. That rules out a lot of ANSI C compiler only chips.Weakkneed
The C backend feature has been removed since v3.1. "It had numerous problems, to the point of not being able to compile any nontrivial program."Cao
I rolled up comments into the answer and added syntax examples. Hope that helps someone else going down this path!Fulfillment
M
5

While you can do OO in C (e.g. by adding a theType *this first parameter to methods, and manually handling something like vtables for polymorphism) this is never particularly satisfactory as a design, and will look ugly (even with some pre-processor hacks).

I would suggest at least looking at a re-design to compare how this would work out.

Overall a lot depends on the answer to the key question: if you have working C++ code, why do you want C instead?

Mealworm answered 10/4, 2009 at 10:38 Comment(1)
The author's reasons are obviously situationally specific, but reasons do exist. Sometimes a c++ compiler does not exist on a particular platform, or just might not be available for some reason. It also serves as a very excellent learning tool.Thierry
D
5

Maybe good ol' cfront will do?

Damsel answered 3/10, 2012 at 23:5 Comment(1)
As far as I know, cfront hasn't been maintained in a long time and is unlikely to handle modern C++ code.Rootstock
A
4

A compiler consists of two major blocks: the 'front end' and the 'back end'. The front end of a compiler analyzes the source code and builds some form of a 'intermediary representation' of said source code which is much easier to analyze by a machine algorithm than is the source code (i.e. whereas the source code e.g. C++ is designed to help the human programmer to write code, the intermediary form is designed to help simplify the algorithm that analyzes said intermediary form easier). The back end of a compiler takes the intermediary form and then converts it to a 'target language'.

Now, the target language for general-use compilers are assembler languages for various processors, but there's nothing to prohibit a compiler back end to produce code in some other language, for as long as said target language is (at least) as flexible as a general CPU assembler.

Now, as you can probably imagine, C is definitely as flexible as a CPU's assembler, such that a C++ to C compiler is really no problem to implement from a technical pov.

So you have: C++ ---frontEnd---> someIntermediaryForm ---backEnd---> C

You may want to check these guys out: http://www.edg.com/index.php?location=c_frontend (the above link is just informative for what can be done, they license their front ends for tens of thousands of dollars)

PS As far as i know, there is no such a C++ to C compiler by GNU, and this totally beats me (if i'm right about this). Because the C language is fairly small and it's internal mechanisms are fairly rudimentary, a C compiler requires something like one man-year work (i can tell you this first hand cause i wrote such a compiler myself may years ago, and it produces a [virtual] stack machine intermediary code), and being able to have a maintained, up-to-date C++ compiler while only having to write a C compiler once would be a great thing to have...

Amontillado answered 10/1, 2013 at 16:35 Comment(2)
the target language for general-use compilers are assembler languages ( or machine code?? ) for various processorsTomfool
EDG dropped their C front end unforunatelyFulfillment
M
2

This is an old thread but apparently the C++ Faq has a section (Archived 2013 version) on this. This apparently will be updated if the author is contacted so this will probably be more up to date in the long run, but here is the current version:

Depends on what you mean. If you mean, Is it possible to convert C++ to readable and maintainable C-code? then sorry, the answer is No — C++ features don't directly map to C, plus the generated C code is not intended for humans to follow. If instead you mean, Are there compilers which convert C++ to C for the purpose of compiling onto a platform that yet doesn't have a C++ compiler? then you're in luck — keep reading.

A compiler which compiles C++ to C does full syntax and semantic checking on the program, and just happens to use C code as a way of generating object code. Such a compiler is not merely some kind of fancy macro processor. (And please don't email me claiming these are preprocessors — they are not — they are full compilers.) It is possible to implement all of the features of ISO Standard C++ by translation to C, and except for exception handling, it typically results in object code with efficiency comparable to that of the code generated by a conventional C++ compiler.

Here are some products that perform compilation to C:

  • Comeau Computing offers a compiler based on Edison Design Group's front end that outputs C code.
  • LLVM is a downloadable compiler that emits C code. See also here and here. Here is an example of C++ to C conversion via LLVM.
  • Cfront, the original implementation of C++, done by Bjarne Stroustrup and others at AT&T, generates C code. However it has two problems: it's been difficult to obtain a license since the mid 90s when it started going through a maze of ownership changes, and development ceased at that same time and so it doesn't get bug fixes and doesn't support any of the newer language features (e.g., exceptions, namespaces, RTTI, member templates).

  • Contrary to popular myth, as of this writing there is no version of g++ that translates C++ to C. Such a thing seems to be doable, but I am not aware that anyone has actually done it (yet).

Note that you typically need to specify the target platform's CPU, OS and C compiler so that the generated C code will be specifically targeted for this platform. This means: (a) you probably can't take the C code generated for platform X and compile it on platform Y; and (b) it'll be difficult to do the translation yourself — it'll probably be a lot cheaper/safer with one of these tools.

One more time: do not email me saying these are just preprocessors — they are not — they are compilers.

Math answered 12/3, 2013 at 18:37 Comment(3)
This does not provide an answer to the question.Belfort
The link appears to be broken.Apologist
Comeau Computing appears to be fully dead now.Urumchi

© 2022 - 2024 — McMap. All rights reserved.