Donnée:
int func(int x, int y) { /* ... */ }
l'expression func
est de type fonction. Plus précisément, il est de type int(int, int)
,, C est la syntaxe pour le type "fonction à deux int
paramètres de revenir int
. (Vous ne verrez pas souvent que la syntaxe particulière, car il n'est pas commun de se référer à des types de fonction directement.)
Dans la plupart des contextes, une expression de type de fonction est implicitement converti en un pointeur vers la fonction; dans ce cas, le pointeur est de type int(*)(int, int)
.
Les contextes dans lesquels cette conversion implicite ne pas se produire sont les suivants:
Lorsque l'expression est l'opérateur unaire &
; dans ce cas, &func
rendements de l'adresse de la fonction (comme func
par elle-même généralement le cas); et
Lorsque l'expression est l'opérande de sizeof
. Sans cette exception, sizeof func
donnerait la taille d'un pointeur de fonction. Au lieu de cela, c'est une violation de contrainte, nécessitant un diagnostic du compilateur.
(Une note de côté: Cette conversion ne se produire lorsque le nom de la fonction est utilisée dans un appel de fonction. L' ()
"opérateur" (le standard ne veut pas l'appeler comme ça) nécessite un préfixe de pointeur de fonction type.)
gcc arrive à avoir une extension standard, elle permet l'arithmétique des pointeurs sur des pointeurs de fonction et sur le type void*
, agissant comme l'arithmétique des pointeurs sur char*
des pointeurs (c'est à dire, il fonctionne dans les unités d'octets). Malheureusement, à mon humble avis, gcc n'via une bidouille, la définition de la taille de types de fonctions et de type void
à 1. C'est pourquoi vous obtenez sizeof func == 1
; si vous activez l'un de la norme conforme modes (par exemple, gcc -std=c99 -pedantic
), vous recevrez un avertissement.
D'ailleurs, ne pas utiliser %d
pour imprimer le résultat de l' sizeof
. sizeof
donne un résultat de type size_t
. Si votre application prend en charge (C99 ou plus tard), utilisez %zu
; dans le cas contraire, vous devez utiliser un cast pour convertir explicitement l' size_t
de la valeur à quelque chose que vous pouvez imprimer. Par exemple:
printf("%lu\n", (unsigned long)sizeof &func);