To your generic question, there's no simple answer. C++ only supports a subset of C. If you want to write code that's valid and has the same sematics in both languages, you're very limited. Some examples of C code that's not valid C++ are:
Code that uses keywords of C++ that don't have a special meaning in C like class
, this
, new
etc. To avoid confusion, you normally try to avoid these keywords in C, but it's of course not necessary.
C has designated struct and array initializers and they are often a good idea in a typical C project. You could write for example
struct foo {int a; char b; short c; };
struct foo x = { .b = 'x', .c = 42 };
this isn't valid C++.
In C, you must write struct foo
to refer to a structure with tag foo, while C++ allows to just write foo
. This has a strange consequence when it comes to typedef
s. In C, you could have
struct foo;
typedef struct bar foo;
This is just an example, the code is confusing of course. But it's invalid code in C++, because it would be unclear what you refer to when just writing foo
. Therefore, in C++, a typedef
with the same name as a struct
tag must refer to the exact same type.
C supports flexible array members as the last element of a struct
like this:
struct foo { int x; int a[]; }
The size of a
is determined when you allocate memory for that struct (adding n * sizeof(int)
). This feature doesn't exist in C++
In C, pointer casts are almost always wrong, while they can be used in C++ for casting between a base class and a derived one. Therefore, C has the concept of a generic pointer void *
that can be converted without a cast. In C++, converting to and from void *
requires a cast like with any other pointer type.
These are just the examples that I could think of immediately, there are probably more. So yes, it's never a good idea to compile C code with a C++ compiler.
I used c in a project, and after some study, I found better method with some c++ libraries, but I really don't want to rewrite the code
For this problem, there's another simple solution. Divide your code into multiple translation units. There's no problem at all with a mixed C/C++ project, as long as the C and C++ source files are distinct.
So that means you factor out all the code using your C++ library in a C++ file and compile only that file with a C++ compiler. For the public interface of that C++ module, use extern "C"
declarations and guard them with an #ifdef __cplusplus
to hide them from the C compiler.
The structure could look like this (very simplified), if the part using C++ is in a translation unit called module
here:
module.h:
#ifndef MODULE_H
#define MODULE_H
#ifdef __cplusplus
// the C++ compiler will see this causing all declarations in the block to have C linkage,
// the C compiler won't see it (skipped by the preprocessor)
extern "C" {
#endif
int module_foo(int arg);
#ifdef __cplusplus
}
#endif
#endif
module.cpp:
#include "module.h"
#include <mycpplib> // example
int module_foo(int arg)
{
// some C++ code using your C++ library
}
main.c:
#include "module.h"
int main(void)
{
int x = module_foo(42);
}
You could build a complete program like this:
gcc -c -omain.o main.c
g++ -c -omodule.o module.cpp
# link them together, using the C++ library libmycpplib:
g++ -oprogram main.o module.o -lmycpplib