Acerca de la definición tentativa

Leí de un libro sobre definición tentativa que,

Una definición tentativa es cualquier statement de datos externos que no tenga un especificador de clase de almacenamiento ni un inicializador. Una definición provisional se convierte en una definición completa si se alcanza el final de la unidad de traducción y no ha aparecido ninguna definición con un inicializador para el identificador.

Por favor explique lo que significa la statement anterior. Además, ¿la diferencia entre Declaración y Definición? Me confundí debido a esto. 🙁 Y por qué este progtwig no da un error:

#include  int a; //Tentative definition int a; //similarly this declaration too. int main() //not getting any error with this code why its so? { printf("hi"); } 

Además, ¿qué está mal con este código?

 #include printf("Hi"); int main(void){ return 0; } 

Una statement de variable dice, “hay una variable con el siguiente nombre y tipo en el progtwig”.

Una definición variable dice: “Estimado Sr. Comstackdor, asigne memoria para una variable con el siguiente nombre y escriba ahora”.

Entonces puede haber múltiples declaraciones para la misma variable, pero solo debe haber una definición.

En C, las declaraciones puras (que no son también definiciones) van precedidas de la palabra clave extern . Entonces, como no tiene esta palabra clave en su primer ejemplo, lo que tiene son dos definiciones. Aparentemente, esto parece ser un problema (y de hecho es un error en C ++), pero C tiene una regla especial de “definición provisional” que permite múltiples definiciones para la misma variable siempre que coincidan y como máximo con una tiene un inicializador El comstackdor de C, entre bastidores, combina todas las definiciones tentativas en una sola definición.

Si hubiera intentado inicializar ambas definiciones, así:

 int a = 1; int a = 2; 

Entonces hubieras tenido un error.

Tu segunda pregunta es más directa. En C, simplemente no puede tener instrucciones ejecutables fuera del cuerpo de una función. Simplemente no está permitido. Piénselo: ¿cuándo esperaría que se ejecutara si estuviera permitido?

La primera funciona porque ambas definiciones de a son tentativas, y pueden duplicarse tan a menudo como considere oportuno. Al final de la unidad de traducción, no se ha visto ninguna definición no tentativa, por lo que lo que ha especificado para los atributos se combina con los valores predeterminados para dar una definición final de a , por lo que tendrá una vinculación externa, duración de almacenamiento estático y ser inicializado a 0.

El problema con el segundo no tiene nada que ver con las definiciones tentativas. Su printf("Hi"); necesita estar dentro de una función para funcionar; no es una statement o una definición (provisional o de otro tipo); simplemente no está permitido allí.