Fonction declaree sans aucun paramètre
Le
candide
Bonjour,
Soit le code suivant :
/* -- */
#include <stdio.h>
void test()
{
printf("test");
}
int main ( void )
{
test(421);
return 0;
}
/* -- */
Je n'arrive pas à savoir si ce code est valide. Quand je le compile avec les
options -W -Wall -stdÉ9 -pedantic , il ne me renvoie aucun warning. Est-ce à
dire que gcc considère la définition donnée de la fonction test() comme une
définition pré-normalisation (dite "classique") sans prototype ? Je dirais que
oui vu que la Norme dit assez laconiquement :
-
6.2.7 Compatible type and composite type
§1 ()
If only one type is a function type with a parameter type list (a function
prototype)
-
Franchement, placer une définition entre parenthèses, c'est quand même un peu
fort, non ?
Bon, si c'est ça, gcc aurait pu faire un petit effort d'avertissement.
Maintenant si la fonction admet un prototype :
-
6.7.5.3 Function declarators (including prototypes)
()
An empty list in a function declarator that is part of a definition of that
function specifies that the function has no parameters. The empty list in a
function declarator that is not part of a definition of that function specifies
that no information about the number or types of the parameters is supplied.
-
je dirais que ma liste vide fait partie de la définition de la fonction et donc
que je dois considérer que ma fonction n'admet aucun paramètre. Et donc il
s'agirait d'un UB vu que :
-
6.5.2.2 Function calls
()
If the expression that denotes the called function has a type that includes a
prototype, the number of arguments shall agree with the number of parameters.
-
Qu'en pensez-vous ?
Enfin, il me semble que si la définition
void test()
{
printf("test");
}
avait été écrite :
void test(void)
{
printf("test");
}
il n'y aurait plus aucune ambiguïté, non ?
Soit le code suivant :
/* -- */
#include <stdio.h>
void test()
{
printf("test");
}
int main ( void )
{
test(421);
return 0;
}
/* -- */
Je n'arrive pas à savoir si ce code est valide. Quand je le compile avec les
options -W -Wall -stdÉ9 -pedantic , il ne me renvoie aucun warning. Est-ce à
dire que gcc considère la définition donnée de la fonction test() comme une
définition pré-normalisation (dite "classique") sans prototype ? Je dirais que
oui vu que la Norme dit assez laconiquement :
-
6.2.7 Compatible type and composite type
§1 ()
If only one type is a function type with a parameter type list (a function
prototype)
-
Franchement, placer une définition entre parenthèses, c'est quand même un peu
fort, non ?
Bon, si c'est ça, gcc aurait pu faire un petit effort d'avertissement.
Maintenant si la fonction admet un prototype :
-
6.7.5.3 Function declarators (including prototypes)
()
An empty list in a function declarator that is part of a definition of that
function specifies that the function has no parameters. The empty list in a
function declarator that is not part of a definition of that function specifies
that no information about the number or types of the parameters is supplied.
-
je dirais que ma liste vide fait partie de la définition de la fonction et donc
que je dois considérer que ma fonction n'admet aucun paramètre. Et donc il
s'agirait d'un UB vu que :
-
6.5.2.2 Function calls
()
If the expression that denotes the called function has a type that includes a
prototype, the number of arguments shall agree with the number of parameters.
-
Qu'en pensez-vous ?
Enfin, il me semble que si la définition
void test()
{
printf("test");
}
avait été écrite :
void test(void)
{
printf("test");
}
il n'y aurait plus aucune ambiguïté, non ?

Poser une question


candide a écrit :
Remplace "void test()" par "void test(void)", voire
"static void test(void)" si elle est locale...
Cordialement,
--
Jacques.
Cette déclaration de fonction n'est pas un prototype. Elle accepte
n'importe quoi, mais le comportement reste défini (les valeurs passée
en paramètre sont simplement ignorées) ... On ne code plus comme ça
depuis 1989. Je recommande
void test(void)
qui indique clairement qu'il n'y a pas de paramètres.
-------------- Build: Debug in hello ---------------
Compiling: main.c
Linking console executable: binDebughello.exe
C:devhellomain.c:4: warning: function declaration isn't a prototype
Output size is 18.08 KB
Process terminated with status 0 (0 minutes, 3 seconds)
0 errors, 1 warnings
Il faut surtout prendre le temps de lire les messages ...
Exactement. C'est l'objet de la modification du langage introduite en
1989 (prototypes).
Tiens l'hôpital qui se moque de la charité .... c'est toi qui devrais relire les
options de compilation que j'ai passées et que j'ai pris soin de rappeler dans
mon message. Enfin, j'ai l'habitude avec toi.
Bon, je te la refais :
:~$ cat test.c
#include
void test()
{
printf("testn");/* j'ai ajouté un saut de ligne */
}
int main ( void )
{
test(421);
return 0;
}
:~$ gcc -W -Wall -stdÉ9 -pedantic -o x test.c
:~$ ./x
test
:~$
Donc, comme j'ai dit, AUCUN warning.
Pour avoir ton warning ou équivalent, il faut d'autres options :
:~$ gcc -W -Wall -stdÉ9 -pedantic -Wmissing-prototypes
-o x test.c
test.c:4: attention : no previous prototype for «test»
:~$ gcc -W -Wall -stdÉ9 -pedantic
-Wold-style-definition -o x test.c
test.c: Dans la fonction «test» :
test.c:4: attention : old-style function definition
:~$ gcc -W -Wall -stdÉ9 -pedantic -Wstrict-prototypes
-o x test.c
test.c:4: attention : function declaration isn»t a prototype
:~$
ce que tu aurais dû préciser si tu avais voulu faire une contribution vraiment
pédagogique.
Une question similaire avait été posé sur développez.com,
http://www.developpez.net/forums/d5...ost3528133
Cordialement.
La discussion que tu cites traite plutôt de la validité de la déclaration int
main() laquelle ne semble en fait ne faire aucun doute puisque le texte de la
Norme C99 lui-même l'utilise dans ses exemples (même si les exemples ne sont pas
normatifs) ce qui est assez incroyable puisque cette possibilité est déclarée
par la Norme elle-même comme étant une obsolescence.