Última actualización:2026-10-12
extern en C++ y la especificación de enlace¶
Sobre el autor:¶
Cuenta pública personal de WeChat:

1. Diferencias de compilación entre C++ y C¶
En C++ es frecuente ver en los archivos de cabecera funciones calificadas con extern "C"; ¿para qué sirven? Se usan para que C++ enlace funciones definidas en módulos del lenguaje C.
Aunque C++ es compatible con C, los símbolos que se generan al compilar las funciones de un archivo C++ son distintos de los que genera el lenguaje C. Como C++ admite la sobrecarga de funciones, los símbolos generados al compilar una función de C++ llevan información de los tipos de los parámetros, mientras que los de C no.
Por ejemplo, tras generar el archivo .o de la función int add(int a, int b) con el compilador de C++, add se convierte en algo como add_int_int, mientras que en C sería algo como _add; es decir: la misma función genera símbolos distintos al compilar en C y en C++.
Esto provoca un problema: si en C++ se usan funciones implementadas en lenguaje C, al compilar y enlazar se produce un error que dice que no se encuentran los símbolos correspondientes. Aquí es donde entra extern "C": le dice al enlazador que busque símbolos del lenguaje C como _add, y no los símbolos decorados por C++.
2. C++ llama a funciones de C¶
Ejemplo de C++ llamando a una función de C: al referenciar la cabecera de C, hay que añadir 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;
}
> 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
add.cpp
#include <iostream>
using namespace std;
extern "C" {
#include "add.h"
}
int main() {
std::cout << add(2, 3) << std::endl;
return 0;
}
bazel run basic_content/extern/extern_c++:main
Y, para que el código C sea reutilizable, es decir, que pueda llamarse tanto desde C como desde C++, la cabecera suele escribirse así:
Es decir, cuando C++ llama a esa interfaz, lo hace como si fuera una interfaz de C. Este enfoque evita que quien programa en C++ tenga que escribir un extern C adicional, y las cabeceras de la biblioteca estándar suelen hacer algo parecido; si no, ¿por qué puedes usar directamente las funciones C de stdio.h sin extern C?El código fuente de los casos anteriores:
2. C llama a funciones de C++¶
extern "C" es un error de sintaxis en C; debe colocarse en el archivo de cabecera de C++.
// 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;
}
En resumen, el modo de uso que se deduce es: en las cabeceras del lenguaje C, sus funciones externas solo pueden especificarse como de tipo extern; el lenguaje C no admite la declaración extern "C", y si un archivo .c incluye extern "C" aparece un error de sintaxis al compilar. Por eso todo uso de extern "C" debe colocarse en los archivos relacionados con el programa cpp o en sus cabeceras.
Se resume en las formas siguientes:
(1) C++ llama a funciones de C:
(2) C llama a funciones de C++Ahora bien, a diferencia de que C++ llame a una interfaz de C —C++ sí puede llamar a funciones C ya compiladas—, aquí C llama a C++ simplemente compilando el código C++ como si fuera código C. Es decir, C no puede llamar directamente a las funciones de la biblioteca de C++.
Temas relacionados¶
- Funciones virtuales puras y clases abstractas en C++ | C++那些事
- Aserciones assert en C++ | C++那些事
- Campos de bits en C++ | C++那些事
- Implementar el polimorfismo de C++ en lenguaje C | C++那些事
- const en C++: constantes y modificación | C++那些事
- La familia completa de const en C++ | C++那些事
- El operador de desreferencia * en C++ | C++那些事
- Inicialización y asignación en C++ | C++那些事
- Formas de devolver varios valores en C++ | C++那些事
- La palabra clave mutable en C++ | C++那些事