variable una tipos que programacion inicializar español ejemplos declarar declaracion como c++ declaration definition extern

c++ - una - tipos de variables en programacion



¿Por qué la inicialización de una variable externa localmente dentro de una función genera un error? (5)

Al agregar un inicializador a la declaración, se convierte en una definición de la variable global. Es equivalente a la misma definición sin extern , que es lo que significa su libro cuando dice que "reemplaza al externo".

Si bien las variables globales se pueden declarar (usando extern ) dentro de una función, no se pueden definir allí, solo en el ámbito del espacio de nombres. Es por eso que el segundo fragmento es un error.

Si desea saber por qué los diseñadores de C (de donde estas reglas llegaron a C ++) eligieron permitir declaraciones pero no definiciones, entonces me temo que no conozco la historia del idioma con suficiente detalle para responder.

Este código compila bien:

extern int i = 10; void test() { std::cout << "Hi" << i << std::endl; }

Si bien este da un error:

void test() { extern int i = 10; std::cout << "Hi" << i << std::endl; }

error: ''i'' tiene tanto ''extern'' como inicializador

Leo en C ++ Primer

Cualquier declaración que incluya un inicializador explícito es una definición. Podemos proporcionar un inicializador en una variable definida como externa, pero al hacerlo se reemplaza la externa. Un externo que tiene un inicializador es una definición. Es un error proporcionar un inicializador en un extern dentro de una función .

¿Alguien puede proporcionar una explicación de por qué esto debería ser un error si se realiza localmente en una función, mientras que se permite lo mismo en un ámbito global?


Al principio, debe familiarizarse con la concepción de la vinculación y el significado de la vinculación externa:

Se dice que un nombre tiene un vínculo cuando podría denotar el mismo objeto, referencia, función, tipo, plantilla, espacio de nombres o valor como un nombre introducido por una declaración en otro ámbito:

Cuando un nombre tiene un enlace externo , a la entidad que denota se le puede hacer referencia mediante nombres de ámbitos de otras unidades de traducción o de otros ámbitos de la misma unidad de traducción.
--3.5.6.2 n3242

La función de static que es diferente de extern , extern es solo una solicitud, static es un comando.

El nombre de una función declarada en el alcance del bloque y el nombre de una variable declarada por una declaración externa del alcance del bloque tienen vínculos.

  • Si hay una declaración visible de una entidad con un enlace que tiene el mismo nombre y tipo, ignorando las entidades declaradas fuera del ámbito del espacio de nombres que lo rodea, la declaración del ámbito de bloque declara esa misma entidad y recibe el enlace de la declaración anterior.
  • Si hay más de una entidad coincidente, el programa está mal formado.
  • De lo contrario, si no se encuentra una entidad coincidente, la entidad de ámbito de bloque recibe un enlace externo.

--3.5.6.6 n3242

Por lo tanto, en el ámbito del bloque se recomienda hacer el siguiente procedimiento:

extern int i;//declare it,request the linkage according to 3.5.6.6 above i = 10;//modify it when has link to a defination

Para la declaración externa global es posible convertir la forma

extern int i =10;

a

extern int i;//include in .hpp is recommended int i =10;//global or namespace variable defination


La forma más sencilla de ponerlo:

El propósito de la palabra clave extern es declarar un objeto sin definirlo. Al definirlo, básicamente le está diciendo al compilador "No asigne un valor, sino que asigne un valor". Eso no tiene sentido: nunca debe hacerse, dentro o fuera de una función. La mayoría de los compiladores lo advertirán y procederán de todos modos, o no lo harán en absoluto y darán un error.

Aunque está fuera del alcance de esta pregunta explicar en detalle lo que hace extern , puede que le resulte útil leer las respuestas para esta pregunta .


La razón por la que se define una variable externa dentro de una función no tiene sentido es la siguiente:

Cuando declara un símbolo externo, le está diciendo al compilador que vincule todas estas apariciones de este valor en el mismo símbolo. Cualquier ocurrencia de extern int i; en su programa se enlazaría con el i definido externamente. Mira este ejemplo:

#include <iostream> using namespace std; extern int i; int i = 10; void test() { std::cout << "Hi" << i << std::endl; } int main() { extern int i; i++; test(); }

Este ejemplo debería dar salida a hi11. Sin embargo, si eliminamos el extern en main, generará 10. Esto se debe a que sin extern, i no está enlazando con el i global, sino que está creando su propia copia local de i.

La razón por la que no tiene sentido definir un extern i dentro de una función es que si permitimos que cualquier función "defina" i. ¿Qué función se ejecuta primero? ¿Cuándo se define?

Supongamos que el siguiente ejemplo es válido, ¿cuál sería la salida?

#include <iostream> using namespace std; extern int i; int i = 10; void test() { std::cout << "Hi" << i << std::endl; } void test2() { extern int i = 1000; std::cout<< "HI" << i << std::endl; } void test3() { extern int i; i = 1000; std::cout<< "HI" << i << std::endl; } int main() { extern int i; i++; test(); i = 0; test2(); }

¿Debe la salida de test2 ser 0, o 1000? También mire mi prueba3, aquí estamos diciendo de manera concisa, vincule mi i con la i externa definida, y asigne su valor como 1000. Esto es muy diferente de intentar "inicializar" un valor.

En resumen, las variables externas realmente solo tienen sentido como globales, y deben definirse en el ámbito global. En tus ejemplos, la primera versión tampoco compila para mí. Me parece interesante. Podría valer la pena ver los documentos de estándares para ver si esto se define de manera concisa, o si su compilador podría manejar esto de una manera diseñada para agregar protección adicional ...


extern variables extern se inicializan antes de que se ejecute cualquier función: en.cppreference.com/w/cpp/language/initialization#Non-local_variables

Si se declarara static lugar de extern dentro de un bloque de función, aún tendría una duración de almacenamiento estático , pero su enlace sería local a esa función en lugar de externo . Por lo tanto, se inicializaría cuando la ejecución se ejecute por primera vez a través de esa línea dentro de la función: en.cppreference.com/w/cpp/language/storage_duration#Static_local_variables

Por lo tanto, está bien inicializar las variables static en un bloque de función, pero no está bien inicializar las variables extern allí.