La palabra reservada extern
ya ha sido brevemente
descripta. Le dice al compilador que una variable o
una función existe, incluso si el compilado aún no la ha visto
en el fichero que está siendo compilado en ese momento. Esta
variable o función puede definirse en otro fichero o más abajo
en el fichero actual. A modo de ejemplo:
//: C03:Forward.cpp // Forward function & data declarations #include <iostream> using namespace std; // This is not actually external, but the // compiler must be told it exists somewhere: extern int i; extern void func(); int main() { i = 0; func(); } int i; // The data definition void func() { i++; cout << i; } ///:~
Listado 3.28. C03/Forward.cpp
Cuando el compilador encuentra la declaración extern int
i
sabe que la definición para i
debe
existir en algún sitio como una variable global. Cuando el
compilador alcanza la definición de i
,
ninguna otra declaración es visible, de modo que sabe que ha
encontrado la misma i
declarada anteriormente
en el fichero. Si se hubiera definido i
como
static
, estaría indicando al compilador que
i
se define globalmente (por
extern
), pero también que tiene el ámbito de fichero
(por static
), de modo que el compilador generará un
error.
Para comprender el comportamiento de los programas C y C++, es necesario saber sobre enlazado. En un programa en ejecución, un identificador se representa con espacio en memoria que aloja una variable o un cuerpo de función compilada. El enlazado describe este espacio tal como lo ve el enlazador. Hay dos formas de enlazado: enlace interno y enlace externo.
Enlace interno significa que el espacio se pide para
representar el identificador sólo durante la compilación del
fichero. Otros ficheros pueden utilizar el mismo nombre de
identificador con un enlace interno, o para una variable
global, y el enlazador no encontraría conflictos - se pide un
espacio separado para cada identificador. El enlace interno se
especifica mediante la palabra reservada static
en C
y C++.
Enlace externo significa que se pide sólo un espacio para
representar el identificador para todos los ficheros que se
estén compilando. El espacio se pide una vez, y el enlazador
debe resolver todas las demás referencias a esa ubicación. Las
variables globales y los nombres de función tienen enlace
externo. Son accesibles desde otros ficheros declarándolas con
la palabra reservada extern
. Por defecto, las
variables definidas fuera de todas las funciones (con la
excepción de const
en C++) y las definiciones de las
funciones implican enlace externo. Se pueden forzar
específicamente a tener enlace interno utilizando
static
. Se puede establecer explícitamente que un
identificador tiene enlace externo definiéndolo como
extern
. No es necesario definir una variable o una
función como extern
en C, pero a veces es necesario
para const
en C++.
Las variables automáticas (locales) existen sólo temporalmente, en la pila, mientras se está ejecutando una función. El enlazador no entiende de variables automáticas, de modo que no tienen enlazado.