Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how does extern "C" allow C++ code in a C file?

Tags:

c++

extern-c

In order to use C++ code in a C file, I read that we can just do extern "C" { (where the c++ code goes here)}, but when I try printing something out using cout, I keep getting an error because it does not recognize the library . I think I am just confused on how extern "C" allows you to use C++ code in C.

like image 200
Sandra Delatorre Avatar asked Apr 22 '16 04:04

Sandra Delatorre


3 Answers

The opposite is true. You can use extern C to add code you want to compile as C code using a C++ compiler.

Unless I'm missing something you can't compile C++ code with a C compiler.

like image 168
It'sPete Avatar answered Sep 23 '22 03:09

It'sPete


The extern "C" construct is a C++-specific syntax, no C compiler will understand it.

That's why you will almost always see it paired with some conditional compilation like

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

What extern "C" does is simply to inhibit name mangling meaning that symbols defined in a C++ source file can be used in a C program.

This allows you to have a project with mixed C and C++ sources, and the C source can call the C++ functions that have been defined as extern "C".

Very simple, and stupid, example just to show the point:

Lets say we have a C source file, compiled with a C compiler:

#include <stdio.h>

void foo(void);  // Declare function prototype, so it can be called

int main(void)
{
    printf("Calling foo...\n");
    foo();
    printf("Done\n");

    return 0;
}

Then we have a C++ source file for the foo function:

#include <iostream>

extern "C" void foo()
{
    std::cout << "Hello from foo\n";
}

The C source file is compiled with a C compiler, and the C++ source file is compiled with a C++ compiler. Then the two object files are linked together to form the executable program. Because foo was defined as extern "C" it's symbol name in the object file is not mangled, and the linker can resolve the reference from the object file created by the C compiler.

It works in the other direction as well. Because symbols in C are not mangled the C++ compiler needs to know that, and that is done by declaring the C symbols extern "C", usually in a header file using the conditional compilation as shown above. If extern "C" was not used, the C++ compiler would think that the symbols were C++ symbols, and mangle the names leading to linker problems when the linker can't find the mangled symbols.

Equally stupid example: First a C++ source file

#include <iostream>

extern "C" void bar();  // Declare function prototype as an unmangled symbol

int main()
{
    std::cout << "Calling bar...\n";
    bar();
}

Then the C source file

#include <stdio.h>

void bar(void)
{
    printf("Inside bar\n");
}
like image 27
Some programmer dude Avatar answered Sep 23 '22 03:09

Some programmer dude


extern "C" is a way of putting C code in C++ code. More specifically it tells the compiler to disable certain things like function overloading so that it can also turn off the name mangling. In C++ a simple function like:

int add(int a, int b) {
    return a+b;
}

Will actually get some funky name in the library to denote the parameters so that if you define another function like:

double add(double a, double b) {
    return a+b;
}

That it knows which one to call. You don't want that if you're trying to use a C library and that's what extern "C" is for. All of this being said, extern "C" does not allow C++ in a C program.

like image 24
CrazyCasta Avatar answered Sep 19 '22 03:09

CrazyCasta