Skip to content

Last updated:2026-10-12

C++ extern Linkage Specification

About the Author

WeChat official account:

wechat

1. Compilation Differences Between C++ and C

In C++ you often see functions decorated with extern "C" in header files; what does that do? It is used so that C++ can link against functions defined in C modules.

Although C++ is compatible with C, the symbols generated after compiling a function in a C++ file differ from those generated by the C language. Because C++ supports function overloading, the symbols generated by the C++ compiler carry information about the function's parameter types, while C's do not.

For example, after the function int add(int a, int b) is compiled by a C++ compiler into a .o file, add becomes something like add_int_int, whereas in C it would be something like _add. That is to say: the same function produces different symbols when compiled in C and in C++.

This leads to a problem: if C++ uses a function implemented in C, the compile/link step errors out, saying the corresponding symbol cannot be found. This is where extern "C" comes into play: it tells the linker to look for C-style symbols like _add instead of C++-mangled symbols.

2. C++ Calling a C Function

An example of C++ calling a C function: when including the C header file, you need to add extern "C"

//add.h
#ifndef ADD_H
#define ADD_H
int add(int x,int y);
#endif

//add.c
#include "add.h"

int add(int x,int y) {
    return x+y;
}

//add.cpp
#include <iostream>
#include "add.h"
using namespace std;
int main() {
    add(2,3);
    return 0;
}

Compile:

//Generate add.o file
gcc -c add.c

Link:

g++ add.cpp add.o -o main

Without adding extern "C" you get errors:

> g++ add.cpp add.o -o main                                   
add.o:在函数‘main’中:
add.cpp:(.text+0x0): `main'被多次定义
/tmp/ccH65yQF.o:add.cpp:(.text+0x0):第一次在此定义
/tmp/ccH65yQF.o:在函数‘main’中:
add.cpp:(.text+0xf):对‘add(int, int)’未定义的引用
add.o:在函数‘main’中:
add.cpp:(.text+0xf):对‘add(int, int)’未定义的引用
collect2: error: ld returned 1 exit status

After adding extern "C":

add.cpp

#include <iostream>
using namespace std;
extern "C" {
    #include "add.h"
}
int main() {
    std::cout << add(2, 3) << std::endl;
    return 0;
}

When compiling, be sure to first generate the intermediate file add.o with gcc.

gcc -c add.c 

Then compile:

g++ add.cpp add.o -o main

If you build with bazel, run: bazel run basic_content/extern/extern_c++:main

Usually, to make C code universally usable — callable both from C and from C++ — the header file is often written like this:

#ifdef __cplusplus
extern "C"{
#endif
int add(int x,int y);
#ifdef __cplusplus
}
#endif

That is, when C++ calls this interface, it calls it the C-interface way. This approach means C++ users need no extra extern C, and the standard library headers essentially do the same thing — otherwise, why would you be able to use the C functions in stdio.h directly without extern C?

The source code for the examples above:

2. C Calling a C++ Function

extern "C" is a syntax error in C, so it must go in a C++ header file.

// add.h
#ifndef ADD_H
#define ADD_H
extern "C" {
    int add(int x,int y);
}
#endif

// add.cpp
#include "add.h"

int add(int x,int y) {
    return x+y;
}

// add.c
extern int add(int x,int y);
int main() {
    add(2,3);
    return 0;
}

Compile:

g++ -c add.cpp

Link:

gcc add.c add.o -o main

The source code for the examples above:

To sum up, we can derive the usage rules: in a C header file, its external functions can only be declared extern; the C language does not support the extern "C" declaration, and including extern "C" in a .c file causes a compile syntax error. So all uses of extern "C" go in the files related to the cpp program or in its header files.

This gives the following forms:

(1)C++ calling a C function:

//xx.h
extern int add(...)

//xx.c
int add(){

}

//xx.cpp
extern "C" {
    #include "xx.h"
}

(2)C calling a C++ function

//xx.h
extern "C"{
    int add();
}
//xx.cpp
int add(){

}
//xx.c
extern int add();

Unlike C++ calling a C interface — where C++ really can call the compiled C functions — here, C calling C++ merely compiles the C++ code as if it were C code and then calls it. In other words, C cannot directly call C++ library functions.

Comments