14 votes

Pourquoi une déclaration vide fonctionne-t-elle pour les définitions avec des arguments int mais pas pour les arguments float?

J'ai pensé que la différence est que déclaration ne contient pas de types de paramètres...

Pourquoi cela fonctionne :

int fuc();

int fuc(int i) {
  printf("%d", i);
  return 0;
}

mais cela échoue à la compilation :

int fuc();

int fuc(float f) {
  printf("%f", f);
  return 0;
}

avec le message :

erreur : types en conflit pour ‘fuc’. note : un type d'argument qui bénéficie d'une promotion par défaut ne peut pas correspondre à une déclaration de liste de paramètres vide

29voto

Jerry Coffin Points 237758

Une déclaration:

int f();

...dit au compilateur qu'un identifiant quelconque (f, dans ce cas) nomme une fonction, et lui indique le type de retour de la fonction - mais ne spécifie pas le nombre ou le type des paramètres que la fonction est censée recevoir.

Un prototype:

int f(int, char);

...est autrement similaire, mais spécifie également le nombre/le type des paramètres que la fonction est censée recevoir. S'il ne prend aucun paramètre, vous utilisez quelque chose comme int f(void) pour le spécifier (car laisser les parenthèses vides est une déclaration). Une nouvelle définition de fonction de style:

int f(int a, char b) { 
    // do stuff here...
}

...agit également comme un prototype.

Sans un prototype en portée, le compilateur applique des promotions par défaut aux arguments avant d'appeler la fonction. Cela signifie que tout char ou short est promu en int, et tout float est promu en double. Par conséquent, si vous déclarez (plutôt que de prototyper) une fonction, vous ne voulez pas spécifier de paramètre char, short ou float - appeler une telle chose donnerait/donnera un comportement indéfini. Avec les drapeaux par défaut, le compilateur pourrait bien rejeter le code, car il n'y a pratiquement aucun moyen de l'utiliser correctement. Vous pourriez peut-être trouver un ensemble de drapeaux de compilation qui permettrait de l'accepter mais ce serait plutôt inutile, car vous ne pouvez de toute façon pas l'utiliser...

0voto

ultifinitus Points 833

prototype = déclaration anticipée, donc vous pouvez l'utiliser avant d'indiquer au compilateur ce qu'il fait. Il a toujours des paramètres, cependant.

Utile à bien des égards!

0voto

mu is too short Points 205090

La déclaration int fuc(float); dit au compilateur qu'il existe une fonction fuc qui prend un float et renvoie un int.

La définition int fuc(float f) { /*...*/ } dit au compilateur ce que fuc est en réalité et fournit également la déclaration.

La différence entre une déclaration et une définition est la différence entre dire qu'un chapeau bleu de taille 6 existe et donner à quelqu'un un chapeau bleu de taille 6 : la déclaration indique qu'une telle chose existe, la définition indique que cette chose précise est la chose en question.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X