Pregunta ¿Redefinición permitida en C pero no en C ++?


¿Por qué este código funciona en C pero no en C ++?

int i = 5;
int i; // but if I write int i = 5; again I get error in C also

int main(){

  // using i
}

32
2018-03-17 09:48


origen


Respuestas:


La definición tentativa está permitida en C pero no en C ++.

Una definición tentativa es cualquier declaración de datos externos que no tenga un especificador de clase de almacenamiento ni un inicializador.

C99 6.9.2 / 2

Una declaración de un identificador para un objeto que tiene alcance de archivo sin un inicializadory    sin un especificador de clase de almacenamiento o con el especificador de clase de almacenamiento estático, constituye una   definición tentativa. Si una unidad de traducción contiene una o más definiciones tentativas para un   identi fi cador, y la unidad de traducción no contiene ninguna definición externa para ese identi fi cador, entonces   el comportamiento es exactamente como si la unidad de traducción contiene una declaración de alcance de archivo de ese   identi fi cador, con el tipo compuesto al final de la unidad de traducción, con un inicializador   igual a 0.

Asi que int i es una definición tentativa. El compilador de C combinará todas las definiciones tentativas en una única definición de i.

En C ++ su código está mal formado debido a la Una regla de definición (Sección 3.2 / 1 ISO C ++)

Sin unidad de traducción contendrá más de una definición de cualquier variable, función, tipo de clase, tipo de enumeración o plantilla.


// pero si escribo int i = 5; de nuevo me sale un error en C también

Porque en ese caso ya no es una definición tentativa debido al inicializador (5).


Solo por el bien de la información

J.5.11 Múltiples definiciones externas

Puede haber más de una definición externa para el identificador de un objeto, con o sin el uso explícito de la palabra clave extern; si las definiciones no están de acuerdo, o se inicializa más de una, el comportamiento no está definido (6.9.2).

También mira esto excelente publicación en variables externas.


50
2018-03-17 09:49



Tha se llama definición tentativa. Está permitido solo en C.

Una definición tentativa es cualquier externa   declaración de datos que no tiene almacenamiento   especificador de clase y sin inicializador. UN   definición tentativa se convierte en una completa   definición si el final de la   unidad de traducción se alcanza y no   definición ha aparecido con un   inicializador para el identificador. En   esta situación, el compilador se reserva   espacio no inicializado para el objeto   definido.

Las siguientes declaraciones muestran definiciones normales y definiciones tentativas.

int i1 = 10;         /* definition, external linkage */
static int i2 = 20;  /* definition, internal linkage */
extern int i3 = 30;  /* definition, external linkage */
int i4;              /* tentative definition, external linkage */
static int i5;       /* tentative definition, internal linkage */

int i1;              /* valid tentative definition */
int i2;              /* not legal, linkage disagreement with previous */
int i3;              /* valid tentative definition */
int i4;              /* valid tentative definition */
int i5;              /* not legal, linkage disagreement with previous */

C ++ no admite el concepto de una definición tentativa: una declaración de datos externa sin un especificador de clase de almacenamiento es siempre una definición.

De aquí: Definiciones provisionales


11
2018-03-17 09:48



Para entender mejor la definición provisional, pase por esta


2
2018-03-17 09:52