(sinon, tu fais comment pour passer des long a des fonctions
variadiques, gros malin ?)
Je suppose que c'est en cherchant le spécificateur %l, non ?
Evidemment, si tu confonds les specificites du fonctionnement de printf
avec le passage de parametres a une fonction, tu ne vas pas t'en servir.
Principe de base du C: la bibliotheque standard n'est pas magique. Elle
est implementable en C standard (mais non portable) si tu te donnes des
primitives d'entrees-sorties raisonnables. C'est lie a la genese du C, et
ce principe est encore aujourd'hui respecte.
En particulier, le seul mecanisme dont tu disposes pour avoir des fonctions
a nombre variables de parametres, c'est l'ellipse. Pour invoquer printf,
tu invoques juste une fonction f de prototype
int f(const char *, ...);
C'est le *seul* mecanisme dont dispose le langage pour donner une semantique
a cet appel de fonction, il n'y a pas de magie specifique a printf.
[ ca ne veut pas dire qu'une implementation n'a pas le droit de profiter
du caractere magique de printf, juste que la semantique du langage est
definie pour que ca fonctionne meme sans magie ]
Mais alors à quoi servent les promotions des arguments par défaut
("default argument promotions") ?
Elles servent a rester compatible avec du C sans prototype, ou les choses
fonctionnaient comme cela.
Ca sert a s'assurer que, meme en l'absence
complete de prototype, on a facilement quelque chose qui marche sur des
appels simples de fonction a base de char, short, ou int.
long et double sortent du lot, et necessitent des precautions particulieres:
c'est un compromis d'efficacite.
Rappel: int est sense representer le type entier *natif* du systeme, a
savoir celui qui represente le meilleur compromis en terme d'efficacite.
C'est normal que, par defaut, les parametres entiers soient promus vers
celui-ci. Sur pas mal d'archis, passer explicitement des trucs plus courts
a une fonction necessite des contorsions couteuses en temps.
si tu fais
short d = 42;
printf("%h", d);
ton d sera promu en int lors de l'appel de printf.
(sinon, tu fais comment pour passer des long a des fonctions
variadiques, gros malin ?)
Je suppose que c'est en cherchant le spécificateur %l, non ?
Evidemment, si tu confonds les specificites du fonctionnement de printf
avec le passage de parametres a une fonction, tu ne vas pas t'en servir.
Principe de base du C: la bibliotheque standard n'est pas magique. Elle
est implementable en C standard (mais non portable) si tu te donnes des
primitives d'entrees-sorties raisonnables. C'est lie a la genese du C, et
ce principe est encore aujourd'hui respecte.
En particulier, le seul mecanisme dont tu disposes pour avoir des fonctions
a nombre variables de parametres, c'est l'ellipse. Pour invoquer printf,
tu invoques juste une fonction f de prototype
int f(const char *, ...);
C'est le *seul* mecanisme dont dispose le langage pour donner une semantique
a cet appel de fonction, il n'y a pas de magie specifique a printf.
[ ca ne veut pas dire qu'une implementation n'a pas le droit de profiter
du caractere magique de printf, juste que la semantique du langage est
definie pour que ca fonctionne meme sans magie ]
Mais alors à quoi servent les promotions des arguments par défaut
("default argument promotions") ?
Elles servent a rester compatible avec du C sans prototype, ou les choses
fonctionnaient comme cela.
Ca sert a s'assurer que, meme en l'absence
complete de prototype, on a facilement quelque chose qui marche sur des
appels simples de fonction a base de char, short, ou int.
long et double sortent du lot, et necessitent des precautions particulieres:
c'est un compromis d'efficacite.
Rappel: int est sense representer le type entier *natif* du systeme, a
savoir celui qui represente le meilleur compromis en terme d'efficacite.
C'est normal que, par defaut, les parametres entiers soient promus vers
celui-ci. Sur pas mal d'archis, passer explicitement des trucs plus courts
a une fonction necessite des contorsions couteuses en temps.
si tu fais
short d = 42;
printf("%h", d);
ton d sera promu en int lors de l'appel de printf.
(sinon, tu fais comment pour passer des long a des fonctions
variadiques, gros malin ?)
Je suppose que c'est en cherchant le spécificateur %l, non ?
Evidemment, si tu confonds les specificites du fonctionnement de printf
avec le passage de parametres a une fonction, tu ne vas pas t'en servir.
Principe de base du C: la bibliotheque standard n'est pas magique. Elle
est implementable en C standard (mais non portable) si tu te donnes des
primitives d'entrees-sorties raisonnables. C'est lie a la genese du C, et
ce principe est encore aujourd'hui respecte.
En particulier, le seul mecanisme dont tu disposes pour avoir des fonctions
a nombre variables de parametres, c'est l'ellipse. Pour invoquer printf,
tu invoques juste une fonction f de prototype
int f(const char *, ...);
C'est le *seul* mecanisme dont dispose le langage pour donner une semantique
a cet appel de fonction, il n'y a pas de magie specifique a printf.
[ ca ne veut pas dire qu'une implementation n'a pas le droit de profiter
du caractere magique de printf, juste que la semantique du langage est
definie pour que ca fonctionne meme sans magie ]
Mais alors à quoi servent les promotions des arguments par défaut
("default argument promotions") ?
Elles servent a rester compatible avec du C sans prototype, ou les choses
fonctionnaient comme cela.
Ca sert a s'assurer que, meme en l'absence
complete de prototype, on a facilement quelque chose qui marche sur des
appels simples de fonction a base de char, short, ou int.
long et double sortent du lot, et necessitent des precautions particulieres:
c'est un compromis d'efficacite.
Rappel: int est sense representer le type entier *natif* du systeme, a
savoir celui qui represente le meilleur compromis en terme d'efficacite.
C'est normal que, par defaut, les parametres entiers soient promus vers
celui-ci. Sur pas mal d'archis, passer explicitement des trucs plus courts
a une fonction necessite des contorsions couteuses en temps.
si tu fais
short d = 42;
printf("%h", d);
ton d sera promu en int lors de l'appel de printf.
Antoine Leca a écrit :Enfin, le compilateur attribue le type size_t au résultat, et on
peut passer à la suite.
Je note ce point important. Ainsi le type size_t du résultat n'est pas
ignoré, il est mis de côté en attendant la suite.(...) pour l'expression, on applique les règles de promotions:
l'expression ? de quelle expression tu parles ? strlen("toto") ?
je croyais qu'on n'en parlait plus de celle-là maintenant que son type
a été repéré par le compilateur.
Mais de toute façon, je ne comprends pas pourquoi tu raisonnes en
terme de rang. La norme C90 (je n'ai pas lu C99) définit la promotion
numérique d'abord en terme de type et accessoirement en terme de rang
Je ne vois pas où la norme quand elle parle de promotion numérique
dit qu'un unsigned int reste inchangé.
Par ailleurs, si j'ai bien compris ton exposé, jusqu'à présent le
spécificateur de conversion %u n'a pas été utilisé par le compilateur,
vrai ?
Le compilateur passe ensuite à la génération du code d'appel d'une
fonction variadique
>[...](...) et le résultat de l'expression est passé conformément à son
type
À quoi tu te réfères :
*) de quelle expression parles-tu ? encore de strlen("toto") ?
après promotion: par exemple, si c'est un unsigned long de taille
double de
Tu parles de ce qui représente size_t ?
celle d'un int, il va utiliser deux fois plus de place...
Que vient faire le int ici.
Il y a peut-être un problème de vocabulaire : le terme "conversion"
est employé dans deux contextes différents : d'une part, conversion
au sens
de conversion d'une valeur d'un type dans un autre et d'autre part,
les conversions opérées par les spécificateurs de conversion, les
machins %d, %u, %f, etc.
(...) Puis va faire l'appel à
printf, avec comme paramètre un pointeur vers {'%', 'u', NL, 0} et
d'autre part le 4 (converti): (...)
"converti" en fonction (cf. ce que tu as dit plus haut) du rang de
size_t ?
l'appel de fonction variadique, va analyser la chaîne, repérer le
%u, aller chercher dans les paramètres passés une valeur de type
unsigned
Je comprends pas : il y a encore une conversion.
Je comprends pas "aller chercher dans les paramètres passés". Il n'y a
plus de paramètres, il n'y a que des arguments,
Je comprends pas ce que ça veut dire aller chercher une valeur de type
unsigned.
Et est-la première fois que l'on tient compte de %u ?
Maintenant que se passe-t-il, étape par étape, quand l'instruction
printf("%un",(unsigned)strlen("toto"));
est exécutée ?
Par rapport à ci-dessus, après l'appel à strlen, le résultat subit
une conversion forcée vers unsigned int (ce qui peut provoquer un
appel de fonction ou pas, l'émission de code ou pas, etc.)
Ensuite, au moment de l'évaluation des paramètres dans l'opération
d'appel de fonction variadique, le cas est plus déterministe, il n'y
a pas de promotion.
Et pourquoi ? tu disais tout à l'heure dans le premier exemple que
dans une fonction variadique, les arguments par défaut subissent
la promotion.
promotion. Et plus bas, le paramètre est passé comme unsigned.
"plus bas" ?
Dans le deuxième temps, au moment d'interpréter la conversion %u,
print ira chercher un unsigned, et donc trouvera toujours 4.
On va vers le nord ou vers le sud ? ;) on en est à la compilation ou à
l'exécution ?
Mais pourquoi la norme dit-elle seulement que size_t est un "type
entier non signé" et nous fait-elle des cachoteries ?
Antoine Leca a écrit :
Enfin, le compilateur attribue le type size_t au résultat, et on
peut passer à la suite.
Je note ce point important. Ainsi le type size_t du résultat n'est pas
ignoré, il est mis de côté en attendant la suite.
(...) pour l'expression, on applique les règles de promotions:
l'expression ? de quelle expression tu parles ? strlen("toto") ?
je croyais qu'on n'en parlait plus de celle-là maintenant que son type
a été repéré par le compilateur.
Mais de toute façon, je ne comprends pas pourquoi tu raisonnes en
terme de rang. La norme C90 (je n'ai pas lu C99) définit la promotion
numérique d'abord en terme de type et accessoirement en terme de rang
Je ne vois pas où la norme quand elle parle de promotion numérique
dit qu'un unsigned int reste inchangé.
Par ailleurs, si j'ai bien compris ton exposé, jusqu'à présent le
spécificateur de conversion %u n'a pas été utilisé par le compilateur,
vrai ?
Le compilateur passe ensuite à la génération du code d'appel d'une
fonction variadique
>[...]
(...) et le résultat de l'expression est passé conformément à son
type
À quoi tu te réfères :
*) de quelle expression parles-tu ? encore de strlen("toto") ?
après promotion: par exemple, si c'est un unsigned long de taille
double de
Tu parles de ce qui représente size_t ?
celle d'un int, il va utiliser deux fois plus de place...
Que vient faire le int ici.
Il y a peut-être un problème de vocabulaire : le terme "conversion"
est employé dans deux contextes différents : d'une part, conversion
au sens
de conversion d'une valeur d'un type dans un autre et d'autre part,
les conversions opérées par les spécificateurs de conversion, les
machins %d, %u, %f, etc.
(...) Puis va faire l'appel à
printf, avec comme paramètre un pointeur vers {'%', 'u', NL, 0} et
d'autre part le 4 (converti): (...)
"converti" en fonction (cf. ce que tu as dit plus haut) du rang de
size_t ?
l'appel de fonction variadique, va analyser la chaîne, repérer le
%u, aller chercher dans les paramètres passés une valeur de type
unsigned
Je comprends pas : il y a encore une conversion.
Je comprends pas "aller chercher dans les paramètres passés". Il n'y a
plus de paramètres, il n'y a que des arguments,
Je comprends pas ce que ça veut dire aller chercher une valeur de type
unsigned.
Et est-la première fois que l'on tient compte de %u ?
Maintenant que se passe-t-il, étape par étape, quand l'instruction
printf("%un",(unsigned)strlen("toto"));
est exécutée ?
Par rapport à ci-dessus, après l'appel à strlen, le résultat subit
une conversion forcée vers unsigned int (ce qui peut provoquer un
appel de fonction ou pas, l'émission de code ou pas, etc.)
Ensuite, au moment de l'évaluation des paramètres dans l'opération
d'appel de fonction variadique, le cas est plus déterministe, il n'y
a pas de promotion.
Et pourquoi ? tu disais tout à l'heure dans le premier exemple que
dans une fonction variadique, les arguments par défaut subissent
la promotion.
promotion. Et plus bas, le paramètre est passé comme unsigned.
"plus bas" ?
Dans le deuxième temps, au moment d'interpréter la conversion %u,
print ira chercher un unsigned, et donc trouvera toujours 4.
On va vers le nord ou vers le sud ? ;) on en est à la compilation ou à
l'exécution ?
Mais pourquoi la norme dit-elle seulement que size_t est un "type
entier non signé" et nous fait-elle des cachoteries ?
Antoine Leca a écrit :Enfin, le compilateur attribue le type size_t au résultat, et on
peut passer à la suite.
Je note ce point important. Ainsi le type size_t du résultat n'est pas
ignoré, il est mis de côté en attendant la suite.(...) pour l'expression, on applique les règles de promotions:
l'expression ? de quelle expression tu parles ? strlen("toto") ?
je croyais qu'on n'en parlait plus de celle-là maintenant que son type
a été repéré par le compilateur.
Mais de toute façon, je ne comprends pas pourquoi tu raisonnes en
terme de rang. La norme C90 (je n'ai pas lu C99) définit la promotion
numérique d'abord en terme de type et accessoirement en terme de rang
Je ne vois pas où la norme quand elle parle de promotion numérique
dit qu'un unsigned int reste inchangé.
Par ailleurs, si j'ai bien compris ton exposé, jusqu'à présent le
spécificateur de conversion %u n'a pas été utilisé par le compilateur,
vrai ?
Le compilateur passe ensuite à la génération du code d'appel d'une
fonction variadique
>[...](...) et le résultat de l'expression est passé conformément à son
type
À quoi tu te réfères :
*) de quelle expression parles-tu ? encore de strlen("toto") ?
après promotion: par exemple, si c'est un unsigned long de taille
double de
Tu parles de ce qui représente size_t ?
celle d'un int, il va utiliser deux fois plus de place...
Que vient faire le int ici.
Il y a peut-être un problème de vocabulaire : le terme "conversion"
est employé dans deux contextes différents : d'une part, conversion
au sens
de conversion d'une valeur d'un type dans un autre et d'autre part,
les conversions opérées par les spécificateurs de conversion, les
machins %d, %u, %f, etc.
(...) Puis va faire l'appel à
printf, avec comme paramètre un pointeur vers {'%', 'u', NL, 0} et
d'autre part le 4 (converti): (...)
"converti" en fonction (cf. ce que tu as dit plus haut) du rang de
size_t ?
l'appel de fonction variadique, va analyser la chaîne, repérer le
%u, aller chercher dans les paramètres passés une valeur de type
unsigned
Je comprends pas : il y a encore une conversion.
Je comprends pas "aller chercher dans les paramètres passés". Il n'y a
plus de paramètres, il n'y a que des arguments,
Je comprends pas ce que ça veut dire aller chercher une valeur de type
unsigned.
Et est-la première fois que l'on tient compte de %u ?
Maintenant que se passe-t-il, étape par étape, quand l'instruction
printf("%un",(unsigned)strlen("toto"));
est exécutée ?
Par rapport à ci-dessus, après l'appel à strlen, le résultat subit
une conversion forcée vers unsigned int (ce qui peut provoquer un
appel de fonction ou pas, l'émission de code ou pas, etc.)
Ensuite, au moment de l'évaluation des paramètres dans l'opération
d'appel de fonction variadique, le cas est plus déterministe, il n'y
a pas de promotion.
Et pourquoi ? tu disais tout à l'heure dans le premier exemple que
dans une fonction variadique, les arguments par défaut subissent
la promotion.
promotion. Et plus bas, le paramètre est passé comme unsigned.
"plus bas" ?
Dans le deuxième temps, au moment d'interpréter la conversion %u,
print ira chercher un unsigned, et donc trouvera toujours 4.
On va vers le nord ou vers le sud ? ;) on en est à la compilation ou à
l'exécution ?
Mais pourquoi la norme dit-elle seulement que size_t est un "type
entier non signé" et nous fait-elle des cachoteries ?
Marc Espie a écrit :short d = 42;
printf("%h", d);
ton d sera promu en int lors de l'appel de printf.
OK, ça s'est la promotion des arguments. Une précision quand même :
que ce soit converti, parfait, maintenant quelle conséquence *pratique*
pour l'*utilisateur* de printf() ?
Finalement, pour une utilisation des bons types pour printf, il suffit
de caster par le bon type attendu par la norme.
Ainsi, si mon argument est de type size_t, mon spécificateur va être %u
(car size_t est un type non signé) et je caste sans me poser de
question en unsigned.
D'ailleurs, je ne vois pas pourquoi on lit souvent le cast suivant :
printf("%un", (unsigned long)strlen("toto"));
Marc Espie a écrit :
short d = 42;
printf("%h", d);
ton d sera promu en int lors de l'appel de printf.
OK, ça s'est la promotion des arguments. Une précision quand même :
que ce soit converti, parfait, maintenant quelle conséquence *pratique*
pour l'*utilisateur* de printf() ?
Finalement, pour une utilisation des bons types pour printf, il suffit
de caster par le bon type attendu par la norme.
Ainsi, si mon argument est de type size_t, mon spécificateur va être %u
(car size_t est un type non signé) et je caste sans me poser de
question en unsigned.
D'ailleurs, je ne vois pas pourquoi on lit souvent le cast suivant :
printf("%un", (unsigned long)strlen("toto"));
Marc Espie a écrit :short d = 42;
printf("%h", d);
ton d sera promu en int lors de l'appel de printf.
OK, ça s'est la promotion des arguments. Une précision quand même :
que ce soit converti, parfait, maintenant quelle conséquence *pratique*
pour l'*utilisateur* de printf() ?
Finalement, pour une utilisation des bons types pour printf, il suffit
de caster par le bon type attendu par la norme.
Ainsi, si mon argument est de type size_t, mon spécificateur va être %u
(car size_t est un type non signé) et je caste sans me poser de
question en unsigned.
D'ailleurs, je ne vois pas pourquoi on lit souvent le cast suivant :
printf("%un", (unsigned long)strlen("toto"));
Et bien, je t'invite à te plonger dans la partie 6.3.1.1 de C99 (environ une
page), qui reprend et étend ce concept, d'une manière considéree comme plus
claire que dans la norme C90 (sachant qu'il faut consulter plusieurs
correctifs techniques pour bien maîtriser C90 sur ce point).
Je ne vois pas où la norme quand elle parle de promotion numérique
dit qu'un unsigned int reste inchangé.
Elle ne dit à aucun endroit qu'il est modifié, ce qui revient au même.
Par ailleurs, si j'ai bien compris ton exposé, jusqu'à présent le
spécificateur de conversion %u n'a pas été utilisé par le compilateur,
vrai ?
Oui. En fait, le spécificateur n'est utilisé à aucun moment par le
compilateur
Il y a peut-être un problème de vocabulaire : le terme "conversion"
est employé dans deux contextes différents : d'une part, conversion
au sens
de conversion d'une valeur d'un type dans un autre et d'autre part,
les conversions opérées par les spécificateurs de conversion, les
machins %d, %u, %f, etc.
Pour le compilateur (le premier temps), seuls les premières sont
considérées.
l'appel de fonction variadique, va analyser la chaîne, repérer le
%u, aller chercher dans les paramètres passés une valeur de type
unsigned
Je comprends pas : il y a encore une conversion.
Là c'est moi qui ne comprend pas : je n'ai pas parlé de conversion ci-dessus
(du moins je n'en ai pas eu l'impression).
Sur une machine à pile, dépiler (cf. la remarque ci-dessus).
Si tu considères une implémentation de printf écrite en C, cela revient à un
appel à va_arg(). Qui nécessite de donner un type, ici ce sera unsigned.
Et est-la première fois que l'on tient compte de %u ?
Oui.
printf("%un",(unsigned)strlen("toto"));
Mais ici nous sommes sûrs qu'il n'y a pas d'effet, puisque nous considérons
un unsigned.
Les « cachoteries » sont en fait les degrés de liberté accordés aux uns et
aux autres, comme dans n'importe quel contrat.
Et bien, je t'invite à te plonger dans la partie 6.3.1.1 de C99 (environ une
page), qui reprend et étend ce concept, d'une manière considéree comme plus
claire que dans la norme C90 (sachant qu'il faut consulter plusieurs
correctifs techniques pour bien maîtriser C90 sur ce point).
Je ne vois pas où la norme quand elle parle de promotion numérique
dit qu'un unsigned int reste inchangé.
Elle ne dit à aucun endroit qu'il est modifié, ce qui revient au même.
Par ailleurs, si j'ai bien compris ton exposé, jusqu'à présent le
spécificateur de conversion %u n'a pas été utilisé par le compilateur,
vrai ?
Oui. En fait, le spécificateur n'est utilisé à aucun moment par le
compilateur
Il y a peut-être un problème de vocabulaire : le terme "conversion"
est employé dans deux contextes différents : d'une part, conversion
au sens
de conversion d'une valeur d'un type dans un autre et d'autre part,
les conversions opérées par les spécificateurs de conversion, les
machins %d, %u, %f, etc.
Pour le compilateur (le premier temps), seuls les premières sont
considérées.
l'appel de fonction variadique, va analyser la chaîne, repérer le
%u, aller chercher dans les paramètres passés une valeur de type
unsigned
Je comprends pas : il y a encore une conversion.
Là c'est moi qui ne comprend pas : je n'ai pas parlé de conversion ci-dessus
(du moins je n'en ai pas eu l'impression).
Sur une machine à pile, dépiler (cf. la remarque ci-dessus).
Si tu considères une implémentation de printf écrite en C, cela revient à un
appel à va_arg(). Qui nécessite de donner un type, ici ce sera unsigned.
Et est-la première fois que l'on tient compte de %u ?
Oui.
printf("%un",(unsigned)strlen("toto"));
Mais ici nous sommes sûrs qu'il n'y a pas d'effet, puisque nous considérons
un unsigned.
Les « cachoteries » sont en fait les degrés de liberté accordés aux uns et
aux autres, comme dans n'importe quel contrat.
Et bien, je t'invite à te plonger dans la partie 6.3.1.1 de C99 (environ une
page), qui reprend et étend ce concept, d'une manière considéree comme plus
claire que dans la norme C90 (sachant qu'il faut consulter plusieurs
correctifs techniques pour bien maîtriser C90 sur ce point).
Je ne vois pas où la norme quand elle parle de promotion numérique
dit qu'un unsigned int reste inchangé.
Elle ne dit à aucun endroit qu'il est modifié, ce qui revient au même.
Par ailleurs, si j'ai bien compris ton exposé, jusqu'à présent le
spécificateur de conversion %u n'a pas été utilisé par le compilateur,
vrai ?
Oui. En fait, le spécificateur n'est utilisé à aucun moment par le
compilateur
Il y a peut-être un problème de vocabulaire : le terme "conversion"
est employé dans deux contextes différents : d'une part, conversion
au sens
de conversion d'une valeur d'un type dans un autre et d'autre part,
les conversions opérées par les spécificateurs de conversion, les
machins %d, %u, %f, etc.
Pour le compilateur (le premier temps), seuls les premières sont
considérées.
l'appel de fonction variadique, va analyser la chaîne, repérer le
%u, aller chercher dans les paramètres passés une valeur de type
unsigned
Je comprends pas : il y a encore une conversion.
Là c'est moi qui ne comprend pas : je n'ai pas parlé de conversion ci-dessus
(du moins je n'en ai pas eu l'impression).
Sur une machine à pile, dépiler (cf. la remarque ci-dessus).
Si tu considères une implémentation de printf écrite en C, cela revient à un
appel à va_arg(). Qui nécessite de donner un type, ici ce sera unsigned.
Et est-la première fois que l'on tient compte de %u ?
Oui.
printf("%un",(unsigned)strlen("toto"));
Mais ici nous sommes sûrs qu'il n'y a pas d'effet, puisque nous considérons
un unsigned.
Les « cachoteries » sont en fait les degrés de liberté accordés aux uns et
aux autres, comme dans n'importe quel contrat.
Si mon argument est une taille d'objet « raisonnable », j'utilise %u pour
imprimer, donc je dois transtyper en (unsigned) si le résultat n'a pas déjà
ce type.
Si mon argument peut être n'importe quelle taille d'objet (cas classique
d'un size_t dont on ne sait rien), j'utilise %zu (avec une implémentation
C99, y compris la bibliothèque) et passer le size-t, ou bien %lu et
transtyper en (unsigned long) si je veux rester conforme C90.
Si mon argument est une taille d'objet « raisonnable », j'utilise %u pour
imprimer, donc je dois transtyper en (unsigned) si le résultat n'a pas déjà
ce type.
Si mon argument peut être n'importe quelle taille d'objet (cas classique
d'un size_t dont on ne sait rien), j'utilise %zu (avec une implémentation
C99, y compris la bibliothèque) et passer le size-t, ou bien %lu et
transtyper en (unsigned long) si je veux rester conforme C90.
Si mon argument est une taille d'objet « raisonnable », j'utilise %u pour
imprimer, donc je dois transtyper en (unsigned) si le résultat n'a pas déjà
ce type.
Si mon argument peut être n'importe quelle taille d'objet (cas classique
d'un size_t dont on ne sait rien), j'utilise %zu (avec une implémentation
C99, y compris la bibliothèque) et passer le size-t, ou bien %lu et
transtyper en (unsigned long) si je veux rester conforme C90.
Si mon argument peut être n'importe quelle taille d'objet (cas classique
d'un size_t dont on ne sait rien), j'utilise %zu (avec une implémentation
C99, y compris la bibliothèque) et passer le size-t, ou bien %lu et
transtyper en (unsigned long) si je veux rester conforme C90.
Si mon argument peut être n'importe quelle taille d'objet (cas classique
d'un size_t dont on ne sait rien), j'utilise %zu (avec une implémentation
C99, y compris la bibliothèque) et passer le size-t, ou bien %lu et
transtyper en (unsigned long) si je veux rester conforme C90.
Si mon argument peut être n'importe quelle taille d'objet (cas classique
d'un size_t dont on ne sait rien), j'utilise %zu (avec une implémentation
C99, y compris la bibliothèque) et passer le size-t, ou bien %lu et
transtyper en (unsigned long) si je veux rester conforme C90.
En news:487efd1b$0$27507$, candide va escriure:Marc Espie a écrit :short d = 42;
printf("%h", d);
ton d sera promu en int lors de l'appel de printf.OK, ça s'est la promotion des arguments. Une précision quand même :
que ce soit converti, parfait, maintenant quelle conséquence *pratique*
pour l'*utilisateur* de printf() ?
Aucune. En fait, le h dans
printf("%hd", d);
n'a pas d'utilité technique.
En news:487efd1b$0$27507$426a74cc@news.free.fr, candide va escriure:
Marc Espie a écrit :
short d = 42;
printf("%h", d);
ton d sera promu en int lors de l'appel de printf.
OK, ça s'est la promotion des arguments. Une précision quand même :
que ce soit converti, parfait, maintenant quelle conséquence *pratique*
pour l'*utilisateur* de printf() ?
Aucune. En fait, le h dans
printf("%hd", d);
n'a pas d'utilité technique.
En news:487efd1b$0$27507$, candide va escriure:Marc Espie a écrit :short d = 42;
printf("%h", d);
ton d sera promu en int lors de l'appel de printf.OK, ça s'est la promotion des arguments. Une précision quand même :
que ce soit converti, parfait, maintenant quelle conséquence *pratique*
pour l'*utilisateur* de printf() ?
Aucune. En fait, le h dans
printf("%hd", d);
n'a pas d'utilité technique.
Dans l'article <g5n3tk$7cn$,
Antoine Leca écrit:Si mon argument peut être n'importe quelle taille d'objet (cas classique
d'un size_t dont on ne sait rien), j'utilise %zu (avec une implémentation
C99, y compris la bibliothèque) et passer le size-t, ou bien %lu et
transtyper en (unsigned long) si je veux rester conforme C90.
Mais la solution C90 risque de ne pas fonctionner avec certaines
implémentations C99. Je suppose que tu fais cela avec un système
style autoconf, ou alors que tu écris du code pour une ou plusieurs
plateformes spécifiques.
Dans l'article <g5n3tk$7cn$1@shakotay.alphanet.ch>,
Antoine Leca <root@localhost.invalid> écrit:
Si mon argument peut être n'importe quelle taille d'objet (cas classique
d'un size_t dont on ne sait rien), j'utilise %zu (avec une implémentation
C99, y compris la bibliothèque) et passer le size-t, ou bien %lu et
transtyper en (unsigned long) si je veux rester conforme C90.
Mais la solution C90 risque de ne pas fonctionner avec certaines
implémentations C99. Je suppose que tu fais cela avec un système
style autoconf, ou alors que tu écris du code pour une ou plusieurs
plateformes spécifiques.
Dans l'article <g5n3tk$7cn$,
Antoine Leca écrit:Si mon argument peut être n'importe quelle taille d'objet (cas classique
d'un size_t dont on ne sait rien), j'utilise %zu (avec une implémentation
C99, y compris la bibliothèque) et passer le size-t, ou bien %lu et
transtyper en (unsigned long) si je veux rester conforme C90.
Mais la solution C90 risque de ne pas fonctionner avec certaines
implémentations C99. Je suppose que tu fais cela avec un système
style autoconf, ou alors que tu écris du code pour une ou plusieurs
plateformes spécifiques.
Donc, pour être pratique et ne pas avoir de problème avec le type des
arguments passés à printf, en cas de non conformité, je caste
systématiquement par le type que la norme attend ?
Les « cachoteries » sont en fait les degrés de liberté accordés aux
uns et aux autres, comme dans n'importe quel contrat.
Oui mais finalement ici, le degré de liberté est quasiment inexistant,
Donc, pour être pratique et ne pas avoir de problème avec le type des
arguments passés à printf, en cas de non conformité, je caste
systématiquement par le type que la norme attend ?
Les « cachoteries » sont en fait les degrés de liberté accordés aux
uns et aux autres, comme dans n'importe quel contrat.
Oui mais finalement ici, le degré de liberté est quasiment inexistant,
Donc, pour être pratique et ne pas avoir de problème avec le type des
arguments passés à printf, en cas de non conformité, je caste
systématiquement par le type que la norme attend ?
Les « cachoteries » sont en fait les degrés de liberté accordés aux
uns et aux autres, comme dans n'importe quel contrat.
Oui mais finalement ici, le degré de liberté est quasiment inexistant,
Mais le programmeur a aussi sa part : le concept même de size_t permet
d'avoir le même programme qui s'exécute à la fois sur MSDos (size_t sur
16/32 bits, int sur 16) et sur un OS moderne 64 bits (long sur 64/32 bits
selon que *nix ou Windows, size_td), ce que ne permettait pas le type
unsigned du K&R auquel il a (partiellement) succedé.
Mais le programmeur a aussi sa part : le concept même de size_t permet
d'avoir le même programme qui s'exécute à la fois sur MSDos (size_t sur
16/32 bits, int sur 16) et sur un OS moderne 64 bits (long sur 64/32 bits
selon que *nix ou Windows, size_td), ce que ne permettait pas le type
unsigned du K&R auquel il a (partiellement) succedé.
Mais le programmeur a aussi sa part : le concept même de size_t permet
d'avoir le même programme qui s'exécute à la fois sur MSDos (size_t sur
16/32 bits, int sur 16) et sur un OS moderne 64 bits (long sur 64/32 bits
selon que *nix ou Windows, size_td), ce que ne permettait pas le type
unsigned du K&R auquel il a (partiellement) succedé.