J'ai lu à plusieurs endroits que lors de la déclaration d'une variable externe, la mémoire n'est pas désignée tant que la définition n'est pas faite. J'essayais ce code qui donne une sortie contradictoire dans gcc.
aditya@theMonster:~$ ./a 4
il aurait dû afficher une erreur ou une taille nulle. mais la sortie suivait. veuillez justifier la sortie. Est-ce un exemple d'un autre comportement non défini?
#include <stdio.h>
int main() {
extern int a;
printf("%lu", sizeof(a));
return 0;
}
5 Réponses :
Vous pouvez vous en tirer ici car a n'est jamais réellement utilisé. L'expression sizeof (a) est évaluée au moment de la compilation. Donc, comme un n'est jamais référencé, l'éditeur de liens ne prend pas la peine de le chercher.
Si vous aviez fait cela à la place:
printf("%d\n", a);
Ensuite, le le programme n’aurait pas réussi à créer un lien, imprimant "une référence indéfinie à un" "
La taille d'une variable est la taille de son type de données, qu'il ne s'agisse actuellement que d'un extern ou non. Puisque sizeof est évalué au moment de la compilation, alors que la résolution des symboles est effectuée au moment de la liaison, cela est acceptable.
Même avec -O0 , gcc ne se soucie pas que ce soit extern ; il met 4 dans esi pour l'argument de printf : https://godbolt.org/z/Zv2VYd
Sans déclarer a , cependant, l'une des opérations suivantes échouera: p>
a = 3;
printf("%d\n", a);
int *p = &a;
Le a est un entier, donc sa taille est 4.
Son emplacement (adresse) et sa valeur ne sont actuellement pas connus.
(il est extern quelque part à un autre endroit) < p>
Mais la taille est bien définie.
Il y a effectivement un problème dans votre code, mais pas là où vous vous attendez:
size_t pour la spécification de conversion printf % ld a un comportement non défini si size_t et < code> unsigned long ont des tailles ou des représentations différentes, comme c'est le cas sur de nombreux systèmes (systèmes 16 bits, Windows 64 bits ...). Voici une version corrigée, portable sur les systèmes non conformes C99, dont la bibliothèque C printf pourrait ne pas prendre en charge % zu :
Concernant les raisons pour lesquelles le programme se compile et s'exécute sans erreur:
a est déclarée dans le corps de main avec lien extern : aucun espace n'est alloué pour elle et a code> ne serait pas défini en dehors du corps de main . sizeof (a) est évalué au moment de la compilation comme la valeur constante sizeof (int) , qui se trouve être 4 sur votre plateforme . a n'est générée par le compilateur, donc l'éditeur de liens ne se plaint pas du fait que a n'est défini nulle part. size_t sizeof (expr / var_name / data_type) 1 est un opérateur unaire qui, lorsqu'il n'est pas fourni avec un tableau de longueur variable, n'évalue pas l'expression. Il vérifie simplement le type de données de l'expression.
De même, ici, dans sizeof (a) , le complieur vérifie uniquement le type de données de a qui est int et renvoie donc la taille de int .
Un autre exemple pour dissiper votre confusion est dans sizeof (i ++) , je ne suis pas incrémenté. Son type de données est vérifié et renvoyé.
Un autre exemple:
4 0
vous donnera une sortie sur gcc sous la forme:
void main(){
int p=0;
printf("%zu",sizeof(p=2+3.0));
printf("%d",p);
}
Vous sortez simplement la taille d'un type. C'est parfaitement valable. Etes-vous sûr de comprendre quelle taille fait?
@AdityaGaddhyan: vous pouvez accepter l'une des réponses en cliquant sur la coche grise sous son score et voter pour celles qui vous ont aidé.