Is it possible to put together C and C++ code in application ?

CWC
7 Min Read

After researching over internet in most of the forums, websites i found that putting together C and C++ code in application makes not much sense. We don’t need to do anything specific to call C functions in our code, since C functions are (ignoring a couple of minor caveats that we don’t really need to be concerned with) C++ functions. There is no need to do anything special like implementing a forwarding function in a namespace (unless we want to).

Using “extern C” will ensure our C function has C rather than C++ linkage, but it’s up to we whether we want to go that extra step. Your code will still build and link fine, regardless. It’s only really important if we are writing a library and you want to export that function to be linked into a C program. If we are not doing that then you really don’t need to worry about the external linkage at this point.

Basically, if you are writing code and building it with a C++ compiler, the code will be built as C++. It doesn’t matter if it’s a stand alone function and it doesn’t matter if it only takes native C types, it’ll still be compiled as a C++ function. If you only ever intend to use this in C++ projects then just put C out of your mind, you are coding in C++.

How extern C helps ?

The “extern C” is a helper to avoid c++ name mangling if we were using a self-written c-function or a self-written C library. however, if you add the c functions to your c++ project it makes no difference whether the c functions have got mangled names or not. with name mangling you don’t have problems in a project where the c++ compiler was used for all .c sources as well since the mangled name was used everywhere. also there is an advantage doing so, since you can use the same function name with different argument lists. commercial c libraries and those coming with the compiler already have the extern C switch in their header files.

We should try to avoid calling pure c functions in c++ if we want a straight and elegant design. for all commercial software we will find class libraries which are an equivalent (and better) replacement for using the c function. for your own c functions we could define them in a first step as public static functions of a helper class, say with name ‘Helper’. then replace the c header by the new class header and compile. the compiler will show we all calls as undefined and we can add Helper:: to the function. in a further step we may build more classes and probably have pointer type as argument for some functions which then could be turned to non-member functions of a new class (where ‘this’ can replace the pointer argument).

Note that without the extern “C”, a C++ program will think that your C-function is a C++ function. Each C++ compiler has its own C++ name mangling approach for C++ functions. If the C++ compiler thinks that your function is a C++ function, then it will be looking for a C++ mangled function name rather than a (possible corresponding C-mangled) name.

Since c is a subset of c++ it would be able to compile any c file beside of very few exceptions where c++ is more strict than c, for example regarding implicit cast of a pointer returned by malloc. but these issues easily could be resolved.

Recently I changed the name of several .c file to .cpp and they compiled fine. They were written well, and were fairly simple since they were just wrappers around FORTRAN modules.

Another consideration as to whether to use extern is ease of converting the C-code to C++. It is not always as easy as the above case.

Years ago when I tried to do that, the number of errors were enormous. This case was an entire set of files that I was told to use in our C++ program. Instead of spending a lot of time converting the .c files to C++, I just used the following approach in the .h headers:

#ifdef __cplusplus
extern "C" {
#endif

When compiling a .c file that uses this .h header, the C compiler skips over the extern “C” part.
When compiling a .cpp file that uses this .h header (so that C++ functions can call the C functions), the C++ compiler sees the extern “C” and uses the correct C calling names.

My vague recollection now was that there were about 100 files, and maybe 10,000 LOCs, so by not converting them to C++ saved me a good deal of conversion time. (I recall that they gave me a few weeks to do the job, but I was able to complete the integration in only a couple of days.)

Conclusion

C++ compiler to compile a C file which happens to be good enough to look like C++, then the mangling is purely C++, so no extern “C” is needed, then I agree. In that case, we actually do have a perfectly formed C++ program that just happens to look like C.

In my experience most legacy C modules usually need some tweaking to conform to C++ standard. In those cases, for C++ to call C, we need the extern “C” to quickly be able to absorb those C modules.

Share This Article
Leave a comment

Leave a Reply

Your email address will not be published. Required fields are marked *

English
Exit mobile version