comportement de la déclaration de fonction implicite

Je sais qu’il est faux d’utiliser une fonction sans prototype. Mais lorsque je me suis amusé, j’ai découvert ce comportement étrange et conflictuel .

test1

#include  #include  void main(){ char c='\0'; float f=0.0; xof(c,f);/* at this point implicit function declaration is generated as int xof(int ,double ); */ } int xof(char c,float f) { printf("%d %f\n", c,f); } 

La déclaration de fonction implicite serait int xof (int, double);

l’erreur est

nom_variable.c: 8: 5: erreur: types en conflit pour ‘xof’ int xof (car c, float f)

Je comprends cela parce que la déclaration de fonction générée implicitement (qui définit par défaut les valeurs entières sur INT et les décimales sur DOUBLE) ne correspond pas à la définition de fonction suivante

test2

 #include  #include  void main(){ unsigned int a =UINT_MAX; int b=0; xof(a); /* implicit function declaration should be int xof(int); */ } int xof(unsigned a,int b) { printf("%d %d\n", a,b); } 

la déclaration de fonction implicite serait int xof (int); qui devrait entrer en conflit avec la définition de fonction

Mais cela fonctionne bien (pas d’erreur) et la sortie est avec ‘a’ se comportant comme une valeur ‘int’ et ‘b’ a un ‘garbage indéfini’

-1 12260176

Quelqu’un pourrait-il expliquer cela. Merci d’avance.

Lorsqu’un appel de fonction est rencontré sans définition, la définition implicite générée sera toujours int (*)() , c’est-à-dire une fonction acceptant un nombre non spécifié d’arguments et renvoyant int . Les arguments réels dans l’appel de fonction ne sont pas pris en compte. C’est de là que vient votre idée fausse.

Dans le cas du premier programme, le message d’erreur généré est:

/tmp/x1.c:10: erreur: types en conflit pour ‘xof’
/tmp/x1.c:10: remarque: un type d’argument ayant une promotion par défaut ne peut pas correspondre à une déclaration de liste de noms de parameters vide
/tmp/x1.c:6: erreur: la déclaration implicite précédente de ‘xof’ était là

L’erreur apparaît car la définition de la fonction actuelle contient un ou plusieurs parameters dont les types sont soumis aux règles de promotion par défaut. Plus précisément, tout type entier ayant un rang inférieur à int (un caractère dans ce cas) est promu en int dans une expression. Il en va de même pour l’argument float qui devient un double dans les expressions. En d’autres termes, il est impossible de transmettre des parameters du type correct à cette fonction avec une déclaration implicite.

Le second programme ne génère pas d’erreur car aucun des arguments ( int et unsigned int ) n’est soumis à des règles de promotion par défaut. Dans ce cas, vous appelez un comportement non défini car vous ne transmettez pas le nombre approprié d’arguments des types appropriés. Si vous transmettiez 2 parameters des types corrects, le comportement serait bien défini.

Notez que les déclarations de fonction implicites sont une fonctionnalité C89 et ne sont pas sockets en charge par C99 et les versions ultérieures, bien que certains compilateurs puissent les accepter en mode C99 ou C11 comme extension.