# Mixing C and C++ code

C and C++ are two closely related programming languages. Therefore, it may not come as a surprise to you that you can actually mix C and C++ code in a single program. However, this doesn’t come automatically when you write your code the normal way. In this blog post, I will describe what makes it possible to mix the two languages and how to achieve that in code.

When you compile a source file, the function names are mangled. Name mangling is the process that turns each function name into a unique name (identifier) so that during linking the linker can correctly link each function call to the correct function definition. In C and C++, the names are mangled in different ways. If you write normal C++ code and try to include the header in a C program, the linker will complain that the C++ function you are calling is undefined. Therefore, we must tell the C++ compiler that a function will be used in a C program and it should mangle the name in the C way. The way to do it is to use extern "C" when declaring the functions in C++.

// both ways are OK!
extern "C" void hello1();
extern "C" {
void hello2();
}

void hello1()
{
//...
}

void hello2()
{
//...
}


Now if we compile it and inspect the names, we get the mangled names _hello1 and _hello2.

$g++ -c c_linkage.cc$ nm c_linkage.o
0000000000000000 T _hello1
0000000000000010 T _hello2


If you don’t use extern "C", you would get mangled names __Z6hello1v and __Z6hello2v.

$g++ -c cpp_linkage.cc$ nm cpp_linkage.o
0000000000000000 T __Z6hello1v
0000000000000010 T __Z6hello2v


As you can see, extern "C" lets the compiler mangle the name differently.

## Mixing the code

Now that we know how to control name mangling, let’s see how we can actually call C++ function from C. Basically, you have to make sure that when you compile your C++ code, the compiler sees extern "C" around your function declaration. However, when you compile the C part, the function declaration should appear as normal because, from the C compiler’s point of view, the function is just a normal C function. Of course one way to do it is to create two separate header files. A better way to do it is to use a handy macro,

#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif


The __cplusplus macro is only defined by C++ compilers. Therefore, you can include this header file in both the C and C++ code.

It also works the other way around. When you define the function in C and call it in C++, the C compiler will compile as normal and the C++ compiler will know that the function being called has C name mangling.

## Conclusion

In conclusion, I described the difference between C and C++ linkage and how you can successfully mix C and C++ code by controlling the linkage. There are many cases mixing the two is necessary. For example, the CUDA compiler nvcc by default follows C++ linkage. Therefore, you must change it to C linkage in order to mix C and CUDA code. I hope you find this post useful if you are trying to mix the two languages for whatever use case you might have.