Lorsque nous vérifions la taille d'une fonction en utilisant sizeof()
, nous obtenons toujours 1 octet . Que signifie ce 1 octet?
Lorsque nous vérifions la taille d'une fonction en utilisant sizeof()
, nous obtenons toujours 1 octet . Que signifie ce 1 octet?
Réponses:
C'est une violation de contrainte, et votre compilateur devrait le diagnostiquer. S'il le compile malgré cela, votre programme a un comportement indéfini [merci à @Steve Jessop pour la clarification du mode d'échec, et voir la réponse de @Michael Burr pour savoir pourquoi certains compilateurs permettent cela]: De C11, 6.5.3.4./ 1:
L'
sizeof
opérateur ne doit pas être appliqué à une expression qui a le type de fonction
-std=c11
, pas gnu11
. C'est une extension de compilateur vraiment bizarre.
sizeof(void)
1 dans GNU C.
-std=c11
: quelqu'un devrait renvoyer les -std=c*
options aux normes de publicité. Ils n'activent pas le mode de conformité, ils désactivent simplement les extensions qui empêcheraient la compilation d'un programme bien formé (comme typeof
être un mot-clé, car un programme C bien formé peut l'utiliser comme nom de variable, mais gcc
par défaut, rejetterait cela ). Pour désactiver en outre les extensions qui permettent aux programmes mal formés de passer sans diagnostic, vous avez besoin de -pedantic
ou -pedantic-errors
.
Ce n'est pas un comportement indéfini - la norme du langage C nécessite un diagnostic lors de l'utilisation de l' sizeof
opérateur avec un désignateur de fonction (un nom de fonction) car il s'agit d'une violation de contrainte pour l' sizeof
opérateur.
Cependant, en tant qu'extension du langage C, GCC autorise l'arithmétique sur les void
pointeurs et les pointeurs de fonction, ce qui se fait en traitant la taille d'une void
ou d'une fonction comme 1
. En conséquence, l' sizeof
opérateur évaluera 1
pour void
ou une fonction avec GCC. Voir http://gcc.gnu.org/onlinedocs/gcc/Pointer-Arith.html#Pointer-Arith
Vous pouvez demander à GCC d'émettre un avertissement lors de l'utilisation sizeof
avec ces opérandes en utilisant les options -pedantic
ou -Wpointer-arith
de GCC. Ou faites-en une erreur avec -Werror=pointer-arith
.
sizeof
fonction n'est pas UB (ce que j'ai mentionné à peu près uniquement parce que d'autres réponses ont déclaré que c'était UB). Mais j'ai peut-être confondu cela à cause de la façon dont j'ai structuré la phrase. Pour être plus clair. sizeof
une fonction n'est pas UB (comme plusieurs réponses l'ont affirmé). C'est une violation de contrainte. En tant que tel, il nécessite un diagnostic. GCC l'autorise en tant qu'extension.
Cela signifie que le rédacteur du compilateur a décidé d'une valeur de 1 plutôt que de faire voler les démons de votre nez (en fait, c'était une autre utilisation non définie de sizeof
qui nous a donné cette expression: "le compilateur C lui-même DOIT émettre un diagnostic SI c'est le premier requis diagnostic résultant de votre programme, puis PEUT lui-même faire voler des démons de votre nez (ce qui, au fait, pourrait bien ÊTRE le message de diagnostic documenté) tout comme il PEUT émettre des diagnostics supplémentaires pour d'autres violations des règles de syntaxe ou des contraintes (ou, d'ailleurs, quelle que soit la raison qu'il choisit). " https://groups.google.com/forum/?fromgroups=#!msg/comp.std.c/ycpVKxTZkgw/S2hHdTbv4d8J
De là, il y a un terme d'argot "démons nasaux" pour tout ce qu'un compilateur décide de faire en réponse à une construction non définie. 1
est le démon nasal de ce compilateur pour ce cas.
Comme d'autres l'ont souligné, sizeof () peut prendre n'importe quel identifiant valide, mais il ne retournera pas de résultat valide (un résultat honnêtement vrai et valide) pour les noms de fonction. De plus, cela peut certainement, ou non, entraîner le syndrome des «démons sans nez».
Si vous souhaitez profiler la taille de la fonction de votre programme, vérifiez la carte de l'éditeur de liens, qui se trouve dans le répertoire des résultats intermédiaires (celui où les éléments sont compilés dans .obj / .o ou où se trouve l'image / l'exécutable résultant). Parfois, il existe une option pour générer ou non ce fichier de carte ... il dépend du compilateur / éditeur de liens.
Si vous vouliez la taille d'un pointeur vers une fonction, ils ont tous la même taille, la taille d'un mot d'adressage sur votre cpu.
int x = 1;
mais un seul d'entre eux est autorisé pour un compilateur conforme aux normes. Lorsqu'elle sizeof()
est appliquée à une fonction, elle peut ou non retourner une valeur définie, ou refuser de compiler, ou renvoyer une valeur aléatoire basée sur ce qui se trouve dans un registre particulier à ce moment-là. Les démons nasaux littéraux sont peu probables, mais dans la lettre de la norme.
sizeof
à un pointeur sur une fonction.
-pedantic
), vous avez un compilateur non conforme et chaque programme a un comportement non défini.