c++ - página - enlaces internos html
¿Qué es el enlace externo y el enlace interno? (9)
En términos de ''C'' (porque la palabra clave estática tiene un significado diferente entre ''C'' y ''C ++'')
Vamos a hablar de diferentes alcances en ''C''
ALCANCE: Básicamente es cuánto tiempo puedo ver algo y qué tan lejos.
Variable local: el alcance solo está dentro de una función. Reside en el área STACK de la memoria RAM. Lo que significa que cada vez que se llama a una función todas las variables que forman parte de esa función, incluidos los argumentos de la función, se crean de nuevo y se destruyen una vez que el control sale de la función. (Porque la pila se vacía cada vez que vuelve la función)
Variable estática: El alcance de esto es para un archivo. Es accesible en cualquier parte del archivo.
en el que se declara. Reside en el segmento de datos de la memoria RAM. Dado que esto solo se puede acceder dentro de un archivo y, por lo tanto, de enlace INTERNO. Alguna
Otros archivos no pueden ver esta variable. De hecho, la palabra clave STATIC es la única forma en que podemos introducir algún nivel de datos o función
escondido en ''C''Variable global: el alcance de esto es para una aplicación completa. Es accesible desde cualquier lugar de la aplicación. Las variables globales también residen en el segmento de DATOS, ya que se puede acceder a todas partes en la aplicación y, por lo tanto, a enlaces EXTERNOS.
Por defecto, todas las funciones son globales. En el caso, si necesita ocultar algunas funciones de un archivo externo, puede prefijar la palabra clave estática a la función. :-)
Quiero entender la vinculación externa y la vinculación interna y su diferencia.
También quiero saber el significado de
const
variablesconst
vinculan internamente de forma predeterminada a menos que se declare lo contrario comoextern
.
Antes de hablar sobre la pregunta, es mejor conocer el término unidad de traducción , program y algunos conceptos básicos de C ++ (en realidad, la vinculación es uno de ellos en general) de manera precisa. También deberás saber qué es un scope .
Voy a enfatizar algunos puntos clave, esp. los que faltan en las respuestas anteriores.
La vinculación es una propiedad de un nombre , que se introduce mediante una declaración . Nombres diferentes pueden denotar la misma entidad (normalmente, un objeto o una función). Por lo tanto, hablar sobre la vinculación de una entidad generalmente no tiene sentido, a menos que esté seguro de que la entidad solo será referida por el nombre único de algunas declaraciones específicas (generalmente una declaración, sin embargo).
Tenga en cuenta que un objeto es una entidad, pero una variable no lo es. Mientras se habla de la vinculación de una variable, en realidad se trata del nombre de la entidad denotada (que se introduce mediante una declaración específica). El enlace del nombre se encuentra en uno de los tres: sin enlace, enlace interno o enlace externo.
Diferentes unidades de traducción pueden compartir la misma declaración por encabezado / archivo fuente (sí, es la redacción de la norma) incluida. Así que puedes referir el mismo nombre en diferentes unidades de traducción. Si el nombre declarado tiene un enlace externo, la identidad de la entidad referida por el nombre también se comparte. Si el nombre declarado tiene un enlace interno, el mismo nombre en diferentes unidades de traducción denota diferentes entidades, pero puede referirse a la entidad en diferentes ámbitos de la misma unidad de traducción. Si el nombre no tiene vínculos, simplemente no puede referir a la entidad desde otros ámbitos.
(Vaya ... encontré que lo que escribí era algo así como repetir la redacción estándar ...)
También hay algunos otros puntos confusos que no están cubiertos por la especificación del lenguaje.
- Visibilidad (de un nombre). También es una propiedad del nombre declarado, pero con un significado diferente al enlace .
- Visibilidad (de un efecto secundario) . Esto no está relacionado con este tema.
- Visibilidad (de un símbolo). Esta noción puede ser utilizada por implementaciones reales . En tales implementaciones, un símbolo con visibilidad específica en el código objeto (binario) suele ser el destino asignado desde la definición de la entidad cuyos nombres tienen el mismo enlace específico en el código fuente (C ++). Sin embargo, por lo general no se garantiza uno a uno. Por ejemplo, un símbolo en una imagen de biblioteca dinámica se puede especificar solo compartido en esa imagen internamente desde el código fuente (involucrado con algunas extensiones, generalmente,
__attribute__
o__declspec
) o las opciones del compilador, y la imagen no es el programa completo o el archivo objeto traducido de una unidad de traducción, por lo tanto, ningún concepto estándar puede describirlo con precisión. Dado que símbolo no es un término normativo en C ++, es solo un detalle de implementación, aunque las extensiones relacionadas de dialectos pueden haber sido ampliamente adoptadas. - Accesibilidad. En C ++, esto generalmente se refiere a la propiedad de los miembros de la clase o las clases base , que nuevamente es un concepto diferente no relacionado con el tema.
- Global. En C ++, "global" se refiere a algo de espacio de nombres global o ámbito de espacio de nombres global. Este último es aproximadamente equivalente al alcance del archivo en el lenguaje C. Tanto en C como en C ++, el enlace no tiene nada que ver con el alcance, aunque el alcance (como el enlace) también está estrechamente relacionado con un identificador (en C) o un nombre (en C ++) introducido por alguna declaración.
La regla de vinculación de la variable const
ámbito del espacio de nombres es algo especial (y particularmente diferente al objeto const
declarado en el alcance del archivo en lenguaje C, que también tiene el concepto de vinculación de identificadores). Como C ++ impone la ODR , es importante mantener no más de una definición de la misma variable o función que ocurrió en todo el programa, excepto las funciones en inline
. Si no existe tal regla especial de const
, la declaración más simple de const
variable con inicializadores (por ejemplo, = xxx
) en un encabezado o en un archivo fuente (a menudo un "archivo de encabezado") incluido por varias unidades de traducción (o incluido por una unidad de traducción) más de una vez, aunque rara vez) en un programa violará la ODR, lo que hace imposible utilizar la variable const
como reemplazo de algunas macros similares a objetos.
Como dudewat dijo que enlace externo significa que el símbolo (función o variable global) es accesible a través de su programa y enlace interno significa que solo es accesible en una unidad de traducción .
Puede controlar explícitamente la vinculación de un símbolo utilizando las palabras clave extern
y static
. Si no se especifica el enlace, el enlace predeterminado es extern
para los símbolos no const
y static
(interno) para los símbolos const
.
// in namespace or global scope
int i; // extern by default
const int ci; // static by default
extern const int eci; // explicitly extern
static int si; // explicitly static
// the same goes for functions (but there are no const functions)
int foo(); // extern by default
static int bar(); // explicitly static
Tenga en cuenta que en lugar de usar static
para enlaces internos, es mejor usar espacios de nombres anónimos en los que también puede poner class
. El enlace para los espacios de nombres anónimos ha cambiado entre C ++ 98 y C ++ 11, pero lo principal es que no se puede acceder a ellos desde otras unidades de traducción.
namespace {
int i; // external linkage but unreachable from other translation units.
class invisible_to_others { };
}
Creo que la vinculación interna y externa en C ++ da una explicación clara y concisa:
Una unidad de traducción se refiere a un archivo de implementación (.c / .cpp) y a todos los archivos de encabezado (.h / .hpp) que incluye. Si un objeto o función dentro de dicha unidad de traducción tiene enlace interno, entonces ese símbolo específico solo es visible para el enlazador dentro de esa unidad de traducción. Si un objeto o función tiene un enlace externo, el enlazador también puede verlo cuando procesa otras unidades de traducción. La palabra clave estática, cuando se usa en el espacio de nombres global, obliga a un símbolo a tener un enlace interno. La palabra clave externa da como resultado un símbolo que tiene un enlace externo.
El compilador omite la vinculación de símbolos tal que:
Las variables globales no constantes tienen un enlace externo por defecto
Las variables globales const tienen vinculación interna por defecto
Las funciones tienen enlace externo por defecto
Cuando escribe un archivo de implementación ( .cpp
, .cpp
, etc.) su compilador genera una unidad de traducción . Este es el archivo de objeto de su archivo de implementación más todos los encabezados que #include
d en él.
El enlace interno se refiere a todo solo en el ámbito de una unidad de traducción .
El enlace externo se refiere a cosas que existen más allá de una unidad de traducción particular. En otras palabras, accesible a través de todo el programa , que es la combinación de todas las unidades de traducción (o archivos de objeto).
La vinculación determina si los identificadores que tienen nombres idénticos se refieren al mismo objeto, función u otra entidad, incluso si esos identificadores aparecen en diferentes unidades de traducción. El enlace de un identificador depende de cómo fue declarado. Hay tres tipos de enlaces:
- Enlace interno : los identificadores solo se pueden ver dentro de una unidad de traducción.
- Enlace externo : los identificadores pueden verse (y referirse) en otras unidades de traducción.
- Sin enlace : los identificadores solo se pueden ver en el ámbito en el que están definidos. La vinculación no afecta el alcance
Solo C ++ : también puede tener vínculos entre fragmentos de código C ++ y no C ++, lo que se denomina vínculo de idioma .
Fuente: IBM Program Linkage
Básicamente
-
extern linkage
variable deextern linkage
es visible en todos los archivos -
internal linkage
variable deinternal linkage
es visible en un solo archivo.
Explique: las variables const se vinculan internamente de manera predeterminada a menos que se declare lo contrario como extern
- Por defecto, la variable global es
external linkage
- pero, la variable global
const
esinternal linkage
- extra,
extern const
variable globalextern const
esexternal linkage
Un material bastante bueno sobre vinculación en C ++
http://www.goldsborough.me/c/c++/linker/2016/03/30/19-34-25-internal_and_external_linkage_in_c++/
En c ++
Cualquier variable en el alcance del archivo y que no esté anidada dentro de una clase o función, es visible en todas las unidades de traducción en un programa. Esto se denomina enlace externo porque en el momento del enlace el nombre es visible para el enlazador en todas partes, externo a esa unidad de traducción.
Las variables globales y las funciones ordinarias tienen un enlace externo.
El objeto estático o el nombre de la función en el alcance del archivo es local a la unidad de traducción. Eso se llama como Enlace Interno
La vinculación se refiere solo a los elementos que tienen direcciones en el momento del enlace / carga; por lo tanto, las declaraciones de clase y las variables locales no tienen vinculación.
- Una variable global tiene un enlace externo por defecto. Su alcance se puede extender a otros archivos que no lo contengan al dar una declaración externa coincidente en el otro archivo.
- El alcance de una variable global se puede restringir al archivo que contiene su declaración prefijando la declaración con la palabra clave static . Se dice que tales variables tienen un enlace interno .
Considere el siguiente ejemplo:
1.cpp
void f(int i);
extern const int max = 10;
int n = 0;
int main()
{
int a;
//...
f(a);
//...
f(a);
//...
}
- La firma de la función f declara f como una función con enlace externo (predeterminado). Su definición se debe proporcionar más adelante en este archivo o en otra unidad de traducción (que figura a continuación).
- max se define como una constante entera El enlace predeterminado para las constantes es interno . Su enlace se cambia a externo con la palabra clave extern . Así que ahora se puede acceder a max en otros archivos.
- n se define como una variable entera. El enlace predeterminado para las variables definidas fuera de los cuerpos de función es externo .
2.cpp
#include <iostream>
using namespace std;
extern const int max;
extern int n;
static float z = 0.0;
void f(int i)
{
static int nCall = 0;
int a;
//...
nCall++;
n++;
//...
a = max * z;
//...
cout << "f() called " << nCall << " times." << endl;
}
- Se declara que max tiene enlace externo . Una definición coincidente para max (con enlace externo) debe aparecer en algún archivo. (Como en 1.cpp)
- n se declara tener enlace externo .
- z se define como una variable global con enlace interno .
- La definición de nCall especifica que nCall es una variable que conserva su valor en las llamadas a la función f (). A diferencia de las variables locales con la clase de almacenamiento automático predeterminada, nCall se inicializará solo una vez al inicio del programa y no una vez por cada invocación de f (). El estático del especificador de la clase de almacenamiento afecta a la vida útil de la variable local y no a su alcance.
NB: la palabra clave static desempeña un doble papel. Cuando se utiliza en las definiciones de variables globales, especifica la vinculación interna . Cuando se usa en las definiciones de las variables locales, especifica que la vida útil de la variable será la duración del programa en lugar de la duración de la función.
¡Espero que ayude!