Combining large C and C++ programs Combining large C and C++ programs unix unix

Combining large C and C++ programs


1) Should I wrap my C header files with extern "C" {}?

2) Should I use extern "C" in my C functions?

Only if you plan to #include the C headers from some C++ source files, i.e., if you want to call one of the C functions from your C++ code. The typical way to make a C header file usable in C++, is like this:

#ifndef MY_C_HEADER_H#define MY_C_HEADER_H#ifdef __cplusplusextern "C" {#endif/* All the original content of the C header */#ifdef __cplusplus}#endif#endif

If you don't want to modify the header, it is also possible to simply apply the extern "C" from the outside of the header when including it in a C++ source file:

// in my_source.cpp (or some C++ header file):extern "C" {#include "my_c_header.h"}

NOTE: Doing that solution is not at all recommended nor is it a long-term / maintainable solution, it is just a quick-and-dirty "just make it work" solution that often fails, but sometimes works, depending on how the C headers look like (C headers don't need to include many other headers, and shouldn't in general, but some authors don't have the common sense to do so).

The reason for extern "C" is to disable C++ name-mangling, i.e., tell the compiler that the functions should be compiled to correspond to un-mangled symbols and/or should be looked up in the symbol table un-mangled (when linking to them). So, the rule is simple, any C++ functions that you want to compile into a library that would be callable from C code (or any other language for that matter) needs to be declared as extern "C". And any function declarations that you which to call in C++ code but links to a library compiled from C (or any other language) must be extern "C" as well.

3) Or should I use extern "C" in my C++ files? (headers? functions? all of them? or only those I need to call from the C program?)

If you want to call some C++ functions from your C code, then those specific functions will have to be declared as extern "C" when compiling that C++ code. In the C header file that declares those functions (for the purpose of calling them from the C code), there is no need for extern "C" (it is always implied in C).

4) In understand I can not have two 'main' functions. Can I simply rename my C++ 'main' function?

What would be the purpose of two main functions? It is not allowed and not useful. You can still just have one "program" with one start and one end, i.e., one main function. You'll have to pick one of the main functions, and add to it whatever extra steps you want (calling the other library). In other words, you have to "merge" the main functions.

5) When compiling in unix, should I use both C (icc) and C++ (icpc) compilers for different files? or just the C++ compiler?

You use the C compiler to compile the C code and a C++ compiler to compile the C++ code. Most build systems (cmake, make, etc.) will automatically do that anyways. Technically, you could try and compile the C code using the C++ compiler, but don't expect it to work right away or even be easy at all to get it working, not worth the effort IMHO.

6) Could it be an option (to simplify things) to convert my main function from C to C++?

That is an option. You source file containing the C main function seems relatively simple, it includes one C header file and has a fairly simple main function. If so, this won't be hard to get to compile on a C++ compiler (unless the C header that it includes is a lot of other C headers, which is bad practice, but likely). You will need to wrap the C header file inclusion with the extern "C" { } as shown above. Then, you can just try to compile it (only the source file containing the main function) in a C++ compiler, and the rest of the C code with the C compiler, and then link the whole thing together. If that works right away, then great, you can start to merge that C main function with the C++ main function from the other library, and you will be good to go.

Otherwise, the usual option is to figure out what you need the C++ code to do. Then, create a C-friendly function (no classes, etc.) in C++ that does these things, using the C++ library. Then, create a header file that declares that function, with the extern "C" specifier (when compiling under C++ only (__cplusplus)), and make sure that this header does not include any other C++ header (not standard headers, not any other headers from the C++ library). And finally, in your C source code, where you have the main function, include that header and call that function(s) from where you need it in the main function. Link the whole thing together and it should work.

7) If I don't need to pass information of classes between the two programs, do I need to do anything about them?

No. As long as you don't include any C++ header from the C code (which the compiler won't accept anyways), the C code is not aware that classes even exist. So, there is no danger here.

8) In what order do you suggest this problem to be tackled? (e.g. first have my C program compiled by C++ compiler; second, compile both codes together with no links; third, link the codes; fourth, rename main in C++ and have it "called" by my C code; fifth, implement the transfer of information?)

First step is, of course, to make sure you can compile both separately. Second step is to see if it is possible to compile the C program's main function (only the main function) with a C++ compiler (as explained above). If successful, start incorporating elements from the C++ main function into that new "merged" main function. If unsuccessful, follow the steps that I just mentioned.

9) Finally, there are some macros in each program, which are repeated (same name, same implementation). Is there a conflict with this? Should I only keep one set of macros?

MACROs... that's hard to tell. If you follow the procedure of creating a C++ function that can be called from the C main function, then you essentially have a perfect isolation of both libraries, i.e., they are compiled separately and linked together after. In that case, there will be no problem with conflicting MACROs (but there might be with functions of the same name, if some are extern "C" in the C++ library). If you try to merge the main functions into one C++ main function, you might have some problems with conflicting MACROs between the C headers and C++ headers which will be included together.


  1. yes but wrapped like explained here : Combining C++ and C - how does #ifdef __cplusplus work?
  2. not needed if they are in the header file. If they are not then you need a forward extern declaration in your C++ files if it needs it and yes with extern "C"
  3. This is not always possible because classes and some C++ typical stuff just does not work in C. But if the C++ code is really just C, it will work too. Using C in C++ is a lot easier than the reverse.
  4. What point is it to rename the second main fnction ? It will not be called, you can have only one main function
  5. you can choose to rename you c files into C++ and start to compile everything with C++. This would resolve your linkage problems with the extern "C" stuff and is what I would do in the first place. Otherwise C is compiled with a C compiler and C++ with a C++ compiler. These compilers behave differently of course.
  6. yes of course, your C code might need some rework though. This is what I would do
  7. don't think so. Then again, there don't seem to be any dependencies ? How can this be ?
  8. does not matter, start compiling, then fix linker problems
  9. might have conflicts if you include 2 header files containing the same macro. Compiler will complain with a redefinition.


Summary:

I think you can just compile your C main() in a separate CPP compilation unit and then "extern C" all your C function definitions. Calling from CPP to C is easy. The other way around is a little more cumbersome as you will have to create "...a C API for exposing the functionality of your C++ code..." - see How to call C++ function from C?

EDIT: Above edited thanks to feedback from Mikael (see comments). Looking at it, I think C++ to C is still generally easier if the C++ code takes advantage of C++ specific features like objects overloading, etc as then it may need C API wappers (see above link). In this case, as Mikael points out, it isn't really the case so either way is as easy / hard...

Note: Combine both your main()'s into the one CPP function.

Detail:

run both programs in such way that my C program "calls" the C++ code

That's usually a little difficult I'm afraid. C++ does something called name mangling, so calling a C++ function from C is difficult to do in a portable fashion, unless you've made a C wrapper (see above link). The reason being is that the CPP compiler (internally without you seeing this) re-writes the function names and includes such things as the parameter types, usually as a suffix to the name, so that it can do things like function overloading. The C compiler doesn't do this because function overloading isn't possible in C.

I'd say it would be better to run your main from a C++ module and call your C functions from there... that way you get around the name mangling issue.

Should I wrap my C header files with extern "C" {}

Yes, it's important in the C header files to wrap all function definitions with this. Normally you'll see something like

#ifndef HEADER_FILE_NAME#define HEADER_FILE_NAME#ifdef __cplusplus   extern "C" {#endif/// FILE CONTENTS#ifdef _cplusplus   }#endif#endif // HEADER_FILE_NAME

What this does is tell the CPP compiler that these function names should not be mangled. This way the correct symbol names will be used when linking with the C functions.

When compiling a CPP module __cplusplus should be defined but when compiling a C module it should not. This means that when the CPP module includes your C header file, it will not mangle the function names and can therefore call the C functions correctly.

Or should I use extern "C" in my C++ files?

The extern "C" just tells the compiler that the function has C language linkage so the generated symbol won't be mangled. So I think, if it is a function that has not been overloaded then doing this (in the H file for the function definition) will prevent the function name being mangles so you'll be able to call it from C. However, if you extern "C" a class for example, that will still have C++ linkage, same for class member functions etc... depends if you use these or not... doesn't look like it from your code sample.

In understand I can not have two main functions. Can I simply rename my C++ main function? Could it be an option (to simplify things) to convert my main function from C to C++?

Yes, I think this is the best option. If only the main() function needs to call both types of code then you're fine. The one main() function written in a CPP compilation unit.

If however there is a C module that needs to call a C++ module then you will need to consider compiling that as a CPP file or making sure that the CPP function is extern "C" and isn't overloaded.

Finally, there are some macros in each program, which are repeated (same name, same implementation). Is there a conflict with this? Should I only keep one set of macros?

If the macros are defined in C/CPP files then you're OK. If they are in header files then there could be a conflict if one file includes two header files which both contain the same macro. In either case i would recommend taking all common macros out into shared header files so that there is only one instance of the macro... much more maintainable... go with the "do not repeat yourself" mantra :)

I haven't addressed all your points, but hope this is enough to get you started :)