What are best practices with regards to C and C++ coding standards? Should developers be allowed to willy-nilly mix them together. Are there any complications when linking C and C++ object files.
Should things like socket libraries that traditionally is written in C remain in C and kept in seperate source files? That is keeping c code in .c files and c++ code in .cpp files. When mixing c and C++ after being parsed with g++ will there be any performance penalties, since typesafe checks are not done in C? but are in C++. Would would be the best way to link C and C++ source code files.
The biggest issue is calling a C function from C++ code or vice versa. In that case, you want to make sure you mark the function as having "C" linkage using extern "C"
. You can do this in the header file directly using:
#if defined( __cplusplus )
extern "C" {
#endif
extern int myfunc( const char *param, int another_one );
#if defined( __cplusplus )
}
#endif
You need the #if
s because C code that includes it won't understand extern "C"
.
If you don't want to (or can't) change the header file, you can do it in the C++ code:
extern "C" {
#include "myfuncheader.h"
}
You can mark a C++ function as having C linkage the same way, and then you can call it from C code. You can't do this for overloaded functions or C++ classes.
Other than that, there should be no problem mixing C and C++. We have a number of decades-old C functions that are still being used by our C++ code.
C++ doesn't do 'typesafe checks' at run time unless you ask for them (by using dynamic_cast
). C++ is highly compatible with C, so you may freely call C libraries as you wish and compile C code with a C++ compiler. C++ does not imply 'object-oriented', and you should get no performance penalty from using it.
If you mix code compiled with gcc and with g++, see Graeme's answer.
One should generally assume that c++ can throw exceptions, hence the c wrapper functions in your block, ought to catch them, and morph them into nice error codes that the c caller can digest.
extern "c"
{
int nice_c_function_interface
(
void
)
{
int returnStatus;
try
{
returnStatus = nice_cpp_function();
}
catch (NiceCppException& that)
{
returnStatus = that.failure_code();
}
catch (...)
{
cerr << "Oh Worse! an unexpected unknown exception" << endl;
returnStatus = -1; // Horrible unknown failure
}
return returnStatus;
}
}
If you have a function in C++ which calls a function in C which in turn calls another function in C++, and this later function throws an exception which should be caught by the first function, you can have problems unless you told the C compiler to enable generation of the exception handling tables.
For gcc, this is the -fexceptions
parameter, which is enabled by default for C++ but disabled by default for C.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With