[Effective-cpp] Item 34: Understand How to Combine C++ and C in the Same Program.
David Sykes
davids at revolution.co.uk
Thu Jun 5 14:53:50 EDT 2003
[I have tried to be concise here, but apologies if I cut too much]
It is perfectly possible to combine C++ code with C code, but once you have
determined that the C++ and C compilers produce compatible object files
there are four things that you need to consider for the combination to
work.
Name Mangling
===========
Function overloading in C++ means having separate functions with the same
name, and to implement this and other features C++ compilers mangle the
function names into something unique for each combination of parameters. In
order for a C program to reference a C++ function, and vice versa, without
knowing specifically how the name is mangled it is necessary to turn the
mangling off for this function. This is achieved using the extern C
directive:
extern "C" function ( type parameter ); // The name of this function will
not be mangled.
Multiple functions can be grouped, and the __cplusplus definition utilised
so that the directives will compile for C as well as C++
#ifdef __cplusplus
extern "C" {
#endif
void function1 ( type parameter );
void function2 ( type parameter );
void function3 ( type parameter );
#ifdef __cplusplus
}
#endif
Initialisation of statics
================
In C++ statics and global objects can have constructors, and the code for
these constructors must be called before main begins. To implement this C++
compilers add a secret function call before main that deals with all the
construction. If main is in the C code then the initialisation function
will not be called, and the static and global objects will not be
constructed correctly. For this reason it is preferable for main to be in
the C++ code. The C version of main can be called realMain, and the C++
main calls this
extern "C" int realMain ( int argc , char **argv);
int main ( int argc , char **argv)
{
return realMain ( argc , argv );
}
If you cannot write main in C++ you have a problem, and must find out how
to call the C++ initialisation code from C.
Dynamic Memory Allocation
====================
In general C++ uses new and delete, C uses malloc and free, and the two are
completely incompatible. It is vital to rigorously separate the two.
Sometimes this is not straightforward, however, for example the function
strdup is generally available in C and C++ and produces a new pointer, but
how should it be deleted? It is best to avoid using any functions that can
cause this sort of confustion
Data Structure Compatibility
====================
Object definitions will not compile in C so it is not possible to directly
pass pointers to objects between C and C++. The rules governing the layout
of a struct in C++ are consistent with those of C, however, so it is
therefore safe to pass pointers to structures back and forth between C and
C++. Adding non virtual functions to the C++ version of the struct does not
change the structure layout, so pointers to structs with non virtual
functions will transfer between C and C++. Adding virtual functions,
however, causes structs to use a different memory layout, and transfer is
no longer possible.
In general you should limit what passes between C and C++ to that which
compiles under the C compiler.
David
---------------------------------------------------------------------------
Any views or opinions are solely those of the author and do not necessarily represent those of Revolution Software Ltd unless specifically stated.
This email and any files transmitted are confidential and intended solely for the use of the individual or entity to which they are addressed.
If you have received this email in error, please notify postmaster at revolution.co.uk
---------------------------------------------------------------------------
More information about the Effective-cpp
mailing list