How & why to use extern “C” to disable name mangling in C++

When mixing C and C++ (i.e., a. calling C function from C++; and b. calling C++ function from C), the C++ name mangling causes linking problems. Technically speaking, this issue happens only when the callee functions have been already compiled into binary (most likely, a *.a library file) using the corresponding compiler.

For a better understanding the issue, we start from:

Call C functions from C++

Problem

pure.c:

pure.h:

taint.cpp:

To establish a mixed compiling environment, we compile the object files one by one:

Then we link:

output:

Solution

We define the C function as extern "C" to make it callable from a C++ program.

pure.h(modified):

Then we run the above compile/link commands:

output:

Why

We examine the binary to better understand why:

Firstly we look at pure.o:

output:

Secondly, we look at taint.o using the problematic version pure.h:

output:

As given in the outputs, the actual function names of print do not match from the caller (in C++, __Z5printv ) and the callee(in C, _print ).

If we look at the taint.o using the modified version of pure.h:

This is how the problem is solved.

Call C++ functions from C

This time, I will skip problem and principle but give the solution only.

callee.cpp:

callee.h:

caller.c:

compile & run:

output:

Best practice

name mangling in a word

C++ introduces name mangling to support something that does not exist in C, namely, function overloading, member function etc.

So when calling C++ functions from C, if the functions fall into the categories above, wrapper functions defined as extern "C" should be used.

Self-defined C library

To enable your C library to be used directly by C++ projects, surround the function declaring code with:

We use #ifdef __cplusplus as extern "C" notation can be used only in C++.

3rd party C library

Most likely, nothing is required as the above technique has been applied already. If now, include the header files this way:

So all the functions can be declared as extern "C".

 

 

How to randomly sort an array

In this article, I will introduce a random sort algorithm with a complexity of O(n).

A randomized array is widely used in games (e.g., Poker) and other systems alike. So I assume it is a commonly encountered program difficulty.

The most intuitive approach is slow. To randomly sort elements in an array A and copy the results to B, this approach 1) uses a random generated number as an; 2) fetch the element from array A using the index; 3) checks if the element exists in B already; 4) if not, insert the element in B and 5) If so, goes back to 1) and regenerates a random index again and conducts the check. As the program proceeds and the B grows bigger, it is more likely that a randomly selected element already exists in B, so the algorithm has to redo everything again (regenerate an index, iterate B to check if the element exists) from 5). When the program reaches the very end of the procedure, the performance becomes unacceptably slow.
To avoid the collision, we can remove the element from A once it is selected. The art is about how to remove to achieve O(n):

1) each time we select an element we append it in the new array;
2) we assign the element from the original array with the last element in the tail;
3) we reduce the size of the original array by 1.

And here is the code: