Je n'arrive pas à savoir si ce code est valide. Quand je le compile avec les
options -W -Wall -std=c99 -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.
-------------------------------------------
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.
Bon, si c'est ça, gcc aurait pu faire un petit effort d'avertissement.
-------------- 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 ...
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 ?
Exactement. C'est l'objet de la modification du langage introduite en 1989 (prototypes).
On 1 sep, 02:26, candide <cand...@free.invalid> wrote:
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.
Bon, si c'est ça, gcc aurait pu faire un petit effort d'avertissement.
-------------- 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 ...
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 ?
Exactement. C'est l'objet de la modification du langage introduite en
1989 (prototypes).
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.
Bon, si c'est ça, gcc aurait pu faire un petit effort d'avertissement.
-------------- 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 ...
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 ?
Exactement. C'est l'objet de la modification du langage introduite en 1989 (prototypes).
candide
-ed- a écrit :
Bon, si c'est ça, gcc aurait pu faire un petit effort d'avertissement.
-------------- 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 ...
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 <stdio.h>
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.
-ed- a écrit :
Bon, si c'est ça, gcc aurait pu faire un petit effort d'avertissement.
-------------- 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 ...
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, si c'est ça, gcc aurait pu faire un petit effort d'avertissement.
-------------- 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 ...
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 <stdio.h>
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.
nicolas.sitbon
On 1 sep, 10:49, candide wrote:
-ed- a écrit :
>> Bon, si c'est ça, gcc aurait pu faire un petit effort d'avertissemen t.
> -------------- 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 ...
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 rappel er dans mon message. Enfin, j'ai l'habitude avec toi.
Bon, je te la refais :
:~$ cat test.c #include <stdio.h>
void test() { printf("testn");/* j'ai ajouté un saut de ligne */
}
int main ( void ) {
test(421);
return 0;
}
:~$ gcc -W -Wall -std9 -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 -std9 -pedantic -Wmissing-pr ototypes -o x test.c test.c:4: attention : no previous prototype for «test» :~$ gcc -W -Wall -std9 -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 -std9 -pedantic -Wstrict-pro totypes -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/d596001/c-cpp/c/fonction-main/#post3528133 Cordialement.
On 1 sep, 10:49, candide <cand...@free.invalid> wrote:
-ed- a écrit :
>> Bon, si c'est ça, gcc aurait pu faire un petit effort d'avertissemen t.
> -------------- 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 ...
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 rappel er dans
mon message. Enfin, j'ai l'habitude avec toi.
>> Bon, si c'est ça, gcc aurait pu faire un petit effort d'avertissemen t.
> -------------- 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 ...
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 rappel er dans mon message. Enfin, j'ai l'habitude avec toi.
Bon, je te la refais :
:~$ cat test.c #include <stdio.h>
void test() { printf("testn");/* j'ai ajouté un saut de ligne */
}
int main ( void ) {
test(421);
return 0;
}
:~$ gcc -W -Wall -std9 -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 -std9 -pedantic -Wmissing-pr ototypes -o x test.c test.c:4: attention : no previous prototype for «test» :~$ gcc -W -Wall -std9 -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 -std9 -pedantic -Wstrict-pro totypes -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/d596001/c-cpp/c/fonction-main/#post3528133 Cordialement.
candide
nicolas.sitbon a écrit :
Une question similaire avait été posé sur développez.com, http://www.developpez.net/forums/d596001/c-cpp/c/fonction-main/#post3528133
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.
nicolas.sitbon a écrit :
Une question similaire avait été posé sur développez.com,
http://www.developpez.net/forums/d596001/c-cpp/c/fonction-main/#post3528133
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.
Une question similaire avait été posé sur développez.com, http://www.developpez.net/forums/d596001/c-cpp/c/fonction-main/#post3528133
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.
candide
-ed- a écrit :
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)
C'est bien sûr ça ? Parce que la Norme dit :
6.5.2.2 Function calls Constraints (...) p6 If the expression that denotes the called function has a type that does not include a prototype, the integer promotions are performed on each argument, and arguments that have type float are promoted to double. These are called the default argument promotions. If the number of arguments does not equal the number of parameters, the behavior is undefined.
-ed- a écrit :
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)
C'est bien sûr ça ? Parce que la Norme dit :
6.5.2.2 Function calls
Constraints
(...)
p6 If the expression that denotes the called function has a type that does not
include a prototype, the integer promotions are performed on each argument, and
arguments that have type float are promoted to double. These are called the
default argument promotions. If the number of arguments does not equal the
number of parameters, the behavior is undefined.
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)
C'est bien sûr ça ? Parce que la Norme dit :
6.5.2.2 Function calls Constraints (...) p6 If the expression that denotes the called function has a type that does not include a prototype, the integer promotions are performed on each argument, and arguments that have type float are promoted to double. These are called the default argument promotions. If the number of arguments does not equal the number of parameters, the behavior is undefined.
candide
-ed- a écrit :
Cette déclaration de fonction n'est pas un prototype. Elle accepte n'importe quoi, mais le comportement reste défini
Non, il semble se confirmer que le comportement est indéterminé, cf. la réponse donnée sur clc où j'ai posé la question :
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)
Pas exactement. D'abord cela oblige les paramètres à être étendus (en particulier les float en double, comme pour les varargs); ensuite le comportement est indéfini lorsque les paramètres ne concordent pas en nombre et qualité avec les arguments.
Antoine
Le 01/09/2009 8:17, emmanuel.delahaye écrivit :
void test()
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)
Pas exactement. D'abord cela oblige les paramètres à être étendus (en
particulier les float en double, comme pour les varargs); ensuite le
comportement est indéfini lorsque les paramètres ne concordent pas en
nombre et qualité avec les arguments.
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)
Pas exactement. D'abord cela oblige les paramètres à être étendus (en particulier les float en double, comme pour les varargs); ensuite le comportement est indéfini lorsque les paramètres ne concordent pas en nombre et qualité avec les arguments.