Je me permets de vous demander un brin d'aide, encore.
Je cherche un exemple simple où la conversion par cast est nécessaire. Je trouve rien sans devoir introduire des pointeurs...
Marc Boyer
Pour printf():
#include <stdio.h>
int x = 1234;
printf ("%ldn", (long) x);
Pourquoi imprimer un long quand on a un int ? C'est juste pour l'exemple où il y a une raison qui m'échappe.
L'exemple n'est pas très bon parce qu'il peut être simplifié en
puts("1234");
mais il illustre la nécessité du cast explicite dans les fonctions à nombre variable d'arguments.
-- Richard
Marc Boyer
Richard Delorme wrote:
Emmanuel Delahaye wrote:
#include <stdio.h> int x = 1234; printf ("%ldn", (long) x);
Pourquoi imprimer un long quand on a un int ? C'est juste pour l'exemple où il y a une raison qui m'échappe.
L'exemple n'est pas très bon parce qu'il peut être simplifié en puts("1234");
Laissons ça de côté. Ce que je voulais dire, c'est y a-t-il une raison cachée qui m'échappe pour faire printf ("%dn", (long) x); au lieu de printf ("%dn", x);
mais il illustre la nécessité du cast explicite dans les fonctions à nombre variable d'arguments.
??? Je suis pas spécialiste, mais mon K&R me parle juste de l'"integral promotion", et je ne vois pas en quoi le cast protège de cela.
Marc Boyer -- Lying for having sex or lying for making war? Trust US presidents :-(
Richard Delorme wrote:
Emmanuel Delahaye wrote:
#include <stdio.h>
int x = 1234;
printf ("%ldn", (long) x);
Pourquoi imprimer un long quand on a un int ?
C'est juste pour l'exemple où il y a une raison qui
m'échappe.
L'exemple n'est pas très bon parce qu'il peut être simplifié en
puts("1234");
Laissons ça de côté.
Ce que je voulais dire, c'est y a-t-il une raison cachée
qui m'échappe pour faire
printf ("%dn", (long) x);
au lieu de
printf ("%dn", x);
mais il illustre la nécessité du cast explicite dans les fonctions à
nombre variable d'arguments.
???
Je suis pas spécialiste, mais mon K&R me parle juste de
l'"integral promotion", et je ne vois pas en quoi le cast
protège de cela.
Marc Boyer
--
Lying for having sex or lying for making war? Trust US presidents :-(
#include <stdio.h> int x = 1234; printf ("%ldn", (long) x);
Pourquoi imprimer un long quand on a un int ? C'est juste pour l'exemple où il y a une raison qui m'échappe.
L'exemple n'est pas très bon parce qu'il peut être simplifié en puts("1234");
Laissons ça de côté. Ce que je voulais dire, c'est y a-t-il une raison cachée qui m'échappe pour faire printf ("%dn", (long) x); au lieu de printf ("%dn", x);
mais il illustre la nécessité du cast explicite dans les fonctions à nombre variable d'arguments.
??? Je suis pas spécialiste, mais mon K&R me parle juste de l'"integral promotion", et je ne vois pas en quoi le cast protège de cela.
Marc Boyer -- Lying for having sex or lying for making war? Trust US presidents :-(
Serge Paccalin
Le mardi 17 février 2004 à 16:14, Marc Boyer a écrit dans fr.comp.lang.c :
Je cherche un exemple simple où la conversion par cast est nécessaire. Je trouve rien sans devoir introduire des pointeurs...
Peut-être l'utilisation de fgetc(), qui retourne un int qui est « souvent » un char.
FILE *pFichier = ... int n;
while ((n = fgetc(pFichier)) != EOF) { char c = (char)n; ... }
-- ___________ 2004-02-18 14:05:47 _/ _ _`_`_`_) Serge PACCALIN -- sp ad mailclub.net _L_) Il faut donc que les hommes commencent -'(__) par n'être pas fanatiques pour mériter _/___(_) la tolérance. -- Voltaire, 1763
Le mardi 17 février 2004 à 16:14, Marc Boyer a écrit dans
fr.comp.lang.c :
Je cherche un exemple simple où la conversion par
cast est nécessaire. Je trouve rien sans devoir
introduire des pointeurs...
Peut-être l'utilisation de fgetc(), qui retourne un int qui est
« souvent » un char.
FILE *pFichier = ...
int n;
while ((n = fgetc(pFichier)) != EOF)
{
char c = (char)n;
...
}
--
___________ 2004-02-18 14:05:47
_/ _ _`_`_`_) Serge PACCALIN -- sp ad mailclub.net
_L_) Il faut donc que les hommes commencent
-'(__) par n'être pas fanatiques pour mériter
_/___(_) la tolérance. -- Voltaire, 1763
Le mardi 17 février 2004 à 16:14, Marc Boyer a écrit dans fr.comp.lang.c :
Je cherche un exemple simple où la conversion par cast est nécessaire. Je trouve rien sans devoir introduire des pointeurs...
Peut-être l'utilisation de fgetc(), qui retourne un int qui est « souvent » un char.
FILE *pFichier = ... int n;
while ((n = fgetc(pFichier)) != EOF) { char c = (char)n; ... }
-- ___________ 2004-02-18 14:05:47 _/ _ _`_`_`_) Serge PACCALIN -- sp ad mailclub.net _L_) Il faut donc que les hommes commencent -'(__) par n'être pas fanatiques pour mériter _/___(_) la tolérance. -- Voltaire, 1763
Richard Delorme
Richard Delorme wrote:
Emmanuel Delahaye wrote:
#include <stdio.h> int x = 1234; printf ("%ldn", (long) x);
Pourquoi imprimer un long quand on a un int ? C'est juste pour l'exemple où il y a une raison qui m'échappe.
L'exemple n'est pas très bon parce qu'il peut être simplifié en puts("1234");
Laissons ça de côté. Ce que je voulais dire, c'est y a-t-il une raison cachée qui m'échappe pour faire printf ("%dn", (long) x);
Attention, tu as oublié un l, ce qui provoque un comportement indéfini. Il fallait lire : printf ("%ldn", (long) x);
au lieu de printf ("%dn", x);
Le problème est la correspondance exact entre le type attendu par printf et le type passé en argument.
mais il illustre la nécessité du cast explicite dans les fonctions à nombre variable d'arguments.
??? Je suis pas spécialiste, mais mon K&R me parle juste de l'"integral promotion", et je ne vois pas en quoi le cast protège de cela.
Il y a une promotion automatique des entiers de rangs inférieurs (_Bool, char ,short, champs de bits de type int ou _Bool), vers int (ou unsigned int), mais pas de long ni de long long vers int. Donc on a :
char c = 3; int x = 1234; long l = 42;
printf("%dn", c); // ok, promotion automatique de char en int printf("%dn", x); // ok, int printf("%dn", l); // pas bon, int attendu, long envoyé printf("%dn", (int)l); // ok printf("%ldn", x); // pas bon, long attendu, int envoyé printf("%ldn", (long) x); // ok
Dans ce dernier exemple, le cast en long est obligatoire à cause du format %ld du printf. Son absence, ou plus généralement la non correspondance entre le type demandé par le format et le type reçu est un UB.
Par contre, si tu as une fonction normale avec un prototype, il n'y a pas de problème :
void f(long x);
f(c); // ok, promotion en long f(x); // ok, promotion en long f(l); // ok, long
J'espère que c'est plus clair.
-- Richard
Richard Delorme wrote:
Emmanuel Delahaye wrote:
#include <stdio.h>
int x = 1234;
printf ("%ldn", (long) x);
Pourquoi imprimer un long quand on a un int ?
C'est juste pour l'exemple où il y a une raison qui
m'échappe.
L'exemple n'est pas très bon parce qu'il peut être simplifié en
puts("1234");
Laissons ça de côté.
Ce que je voulais dire, c'est y a-t-il une raison cachée
qui m'échappe pour faire
printf ("%dn", (long) x);
Attention, tu as oublié un l, ce qui provoque un comportement indéfini.
Il fallait lire :
printf ("%ldn", (long) x);
au lieu de
printf ("%dn", x);
Le problème est la correspondance exact entre le type attendu par printf
et le type passé en argument.
mais il illustre la nécessité du cast explicite dans les fonctions à
nombre variable d'arguments.
???
Je suis pas spécialiste, mais mon K&R me parle juste de
l'"integral promotion", et je ne vois pas en quoi le cast
protège de cela.
Il y a une promotion automatique des entiers de rangs inférieurs (_Bool,
char ,short, champs de bits de type int ou _Bool), vers int (ou unsigned
int), mais pas de long ni de long long vers int. Donc on a :
char c = 3;
int x = 1234;
long l = 42;
printf("%dn", c); // ok, promotion automatique de char en int
printf("%dn", x); // ok, int
printf("%dn", l); // pas bon, int attendu, long envoyé
printf("%dn", (int)l); // ok
printf("%ldn", x); // pas bon, long attendu, int envoyé
printf("%ldn", (long) x); // ok
Dans ce dernier exemple, le cast en long est obligatoire à cause du
format %ld du printf. Son absence, ou plus généralement la non
correspondance entre le type demandé par le format et le type reçu est
un UB.
Par contre, si tu as une fonction normale avec un prototype, il n'y a
pas de problème :
void f(long x);
f(c); // ok, promotion en long
f(x); // ok, promotion en long
f(l); // ok, long
#include <stdio.h> int x = 1234; printf ("%ldn", (long) x);
Pourquoi imprimer un long quand on a un int ? C'est juste pour l'exemple où il y a une raison qui m'échappe.
L'exemple n'est pas très bon parce qu'il peut être simplifié en puts("1234");
Laissons ça de côté. Ce que je voulais dire, c'est y a-t-il une raison cachée qui m'échappe pour faire printf ("%dn", (long) x);
Attention, tu as oublié un l, ce qui provoque un comportement indéfini. Il fallait lire : printf ("%ldn", (long) x);
au lieu de printf ("%dn", x);
Le problème est la correspondance exact entre le type attendu par printf et le type passé en argument.
mais il illustre la nécessité du cast explicite dans les fonctions à nombre variable d'arguments.
??? Je suis pas spécialiste, mais mon K&R me parle juste de l'"integral promotion", et je ne vois pas en quoi le cast protège de cela.
Il y a une promotion automatique des entiers de rangs inférieurs (_Bool, char ,short, champs de bits de type int ou _Bool), vers int (ou unsigned int), mais pas de long ni de long long vers int. Donc on a :
char c = 3; int x = 1234; long l = 42;
printf("%dn", c); // ok, promotion automatique de char en int printf("%dn", x); // ok, int printf("%dn", l); // pas bon, int attendu, long envoyé printf("%dn", (int)l); // ok printf("%ldn", x); // pas bon, long attendu, int envoyé printf("%ldn", (long) x); // ok
Dans ce dernier exemple, le cast en long est obligatoire à cause du format %ld du printf. Son absence, ou plus généralement la non correspondance entre le type demandé par le format et le type reçu est un UB.
Par contre, si tu as une fonction normale avec un prototype, il n'y a pas de problème :
void f(long x);
f(c); // ok, promotion en long f(x); // ok, promotion en long f(l); // ok, long
J'espère que c'est plus clair.
-- Richard
Marc Boyer
Richard Delorme wrote:
Richard Delorme wrote:
Emmanuel Delahaye wrote:
#include <stdio.h> int x = 1234; printf ("%ldn", (long) x);
Pourquoi imprimer un long quand on a un int ? C'est juste pour l'exemple où il y a une raison qui m'échappe.
L'exemple n'est pas très bon parce qu'il peut être simplifié en puts("1234");
Laissons ça de côté. Ce que je voulais dire, c'est y a-t-il une raison cachée qui m'échappe pour faire printf ("%dn", (long) x);
Attention, tu as oublié un l, ce qui provoque un comportement indéfini. Il fallait lire : printf ("%ldn", (long) x);
Voui, problème de copier/coller.
au lieu de printf ("%dn", x);
Le problème est la correspondance exact entre le type attendu par printf et le type passé en argument.
Mais avec la correction apportée, il y a un intérêt ?
Il y a une promotion automatique des entiers de rangs inférieurs (_Bool, char ,short, champs de bits de type int ou _Bool), vers int (ou unsigned int), mais pas de long ni de long long vers int. Donc on a :
char c = 3; int x = 1234; long l = 42;
printf("%dn", c); // ok, promotion automatique de char en int printf("%dn", x); // ok, int printf("%dn", l); // pas bon, int attendu, long envoyé printf("%dn", (int)l); // ok printf("%ldn", x); // pas bon, long attendu, int envoyé printf("%ldn", (long) x); // ok
Voui, toutes choses que j'avais comprises et que mon compilo a d'ailleurs la gentillesse de signaler.
J'espère que c'est plus clair.
Voui, tout à fait.
Marc Boyer -- Lying for having sex or lying for making war? Trust US presidents :-(
Richard Delorme wrote:
Richard Delorme wrote:
Emmanuel Delahaye wrote:
#include <stdio.h>
int x = 1234;
printf ("%ldn", (long) x);
Pourquoi imprimer un long quand on a un int ?
C'est juste pour l'exemple où il y a une raison qui
m'échappe.
L'exemple n'est pas très bon parce qu'il peut être simplifié en
puts("1234");
Laissons ça de côté.
Ce que je voulais dire, c'est y a-t-il une raison cachée
qui m'échappe pour faire
printf ("%dn", (long) x);
Attention, tu as oublié un l, ce qui provoque un comportement indéfini.
Il fallait lire :
printf ("%ldn", (long) x);
Voui, problème de copier/coller.
au lieu de
printf ("%dn", x);
Le problème est la correspondance exact entre le type attendu par printf
et le type passé en argument.
Mais avec la correction apportée, il y a un intérêt ?
Il y a une promotion automatique des entiers de rangs inférieurs (_Bool,
char ,short, champs de bits de type int ou _Bool), vers int (ou unsigned
int), mais pas de long ni de long long vers int. Donc on a :
char c = 3;
int x = 1234;
long l = 42;
printf("%dn", c); // ok, promotion automatique de char en int
printf("%dn", x); // ok, int
printf("%dn", l); // pas bon, int attendu, long envoyé
printf("%dn", (int)l); // ok
printf("%ldn", x); // pas bon, long attendu, int envoyé
printf("%ldn", (long) x); // ok
Voui, toutes choses que j'avais comprises et que mon
compilo a d'ailleurs la gentillesse de signaler.
J'espère que c'est plus clair.
Voui, tout à fait.
Marc Boyer
--
Lying for having sex or lying for making war? Trust US presidents :-(
#include <stdio.h> int x = 1234; printf ("%ldn", (long) x);
Pourquoi imprimer un long quand on a un int ? C'est juste pour l'exemple où il y a une raison qui m'échappe.
L'exemple n'est pas très bon parce qu'il peut être simplifié en puts("1234");
Laissons ça de côté. Ce que je voulais dire, c'est y a-t-il une raison cachée qui m'échappe pour faire printf ("%dn", (long) x);
Attention, tu as oublié un l, ce qui provoque un comportement indéfini. Il fallait lire : printf ("%ldn", (long) x);
Voui, problème de copier/coller.
au lieu de printf ("%dn", x);
Le problème est la correspondance exact entre le type attendu par printf et le type passé en argument.
Mais avec la correction apportée, il y a un intérêt ?
Il y a une promotion automatique des entiers de rangs inférieurs (_Bool, char ,short, champs de bits de type int ou _Bool), vers int (ou unsigned int), mais pas de long ni de long long vers int. Donc on a :
char c = 3; int x = 1234; long l = 42;
printf("%dn", c); // ok, promotion automatique de char en int printf("%dn", x); // ok, int printf("%dn", l); // pas bon, int attendu, long envoyé printf("%dn", (int)l); // ok printf("%ldn", x); // pas bon, long attendu, int envoyé printf("%ldn", (long) x); // ok
Voui, toutes choses que j'avais comprises et que mon compilo a d'ailleurs la gentillesse de signaler.
J'espère que c'est plus clair.
Voui, tout à fait.
Marc Boyer -- Lying for having sex or lying for making war? Trust US presidents :-(
Antoine Leca
En , Jean-Marc Bourguet va escriure:
char c; if (isprint((unsigned char) c)) {
Si on ne caste pas, on risque d'avoir la mauvaise reponse pour 'ÿ' si char est signe.
Tu m'expliquera comment ton code permet d'éviter cela...
{ signed char c = EOF;
EOF peut parfaitement être inférieur à SCHAR_MIN... Imagine ce qui se passe s'il vaut -224
if (isprint(c)) { printf("%c is printablen", c); } else { printf("0xFF is not printablen");
Meilleur: printf("%#X is not printablen", c & UCHAR_MAX);
}
if (isprint((unsigned char)c)) {
Au secours ! Transtypage indéfini !
<résultat, coupé collé depuis plus bas:>
ÿ is printable
Merci d'apporter de l'eau à mon moulin. ;-). Tu stockes EOF dans c, et ton code, par la magie du transtypage, fait apparaître un 'ÿ' là où il n'y en a pas. C'est bien ce que je veux dénoncer. Et pour éviter cela, il faut _toujours_ utiliser int pour les variables caractères, pas char.
Merci d'avance pour le 'ÿ'!
Malheureusement c'est du vecu... On a eu un client hollandais qui avait un nom avec un ÿ.
D'abord, ton client, il devait avoir un nom en IJ, pas en ÿ (le ÿ, c'est pour des noms de famille français; mais comme en néerlandais IJ se trie à part, certains encodent ij avec ÿ, visuellement c'est acceptable, et hop !, le tri devient correct).
De plus, mon argument, c'est justement qu'il faut pouvoir encoder deux choses différentes: 'ÿ' et EOF. Et pour cela, quand on joue avec le résultat des fonctions getc() et compagnie, cela oblige à utiliser des int, les char ne suffisent pas.
Antoine
En pxby8r0bxxv.fsf@news.bourguet.org, Jean-Marc Bourguet va escriure:
char c;
if (isprint((unsigned char) c)) {
Si on ne caste pas, on risque d'avoir la mauvaise reponse pour 'ÿ'
si char est signe.
Tu m'expliquera comment ton code permet d'éviter cela...
{
signed char c = EOF;
EOF peut parfaitement être inférieur à SCHAR_MIN... Imagine ce qui se passe
s'il vaut -224
if (isprint(c)) {
printf("%c is printablen", c);
} else {
printf("0xFF is not printablen");
Meilleur:
printf("%#X is not printablen", c & UCHAR_MAX);
}
if (isprint((unsigned char)c)) {
Au secours ! Transtypage indéfini !
<résultat, coupé collé depuis plus bas:>
ÿ is printable
Merci d'apporter de l'eau à mon moulin. ;-).
Tu stockes EOF dans c, et ton code, par la magie du transtypage, fait
apparaître un 'ÿ' là où il n'y en a pas. C'est bien ce que je veux dénoncer.
Et pour éviter cela, il faut _toujours_ utiliser int pour les variables
caractères, pas char.
Merci d'avance pour le 'ÿ'!
Malheureusement c'est du vecu... On a eu un client hollandais qui
avait un nom avec un ÿ.
D'abord, ton client, il devait avoir un nom en IJ, pas en ÿ (le ÿ, c'est
pour des noms de famille français; mais comme en néerlandais IJ se trie à
part, certains encodent ij avec ÿ, visuellement c'est acceptable, et hop !,
le tri devient correct).
De plus, mon argument, c'est justement qu'il faut pouvoir encoder deux
choses différentes: 'ÿ' et EOF. Et pour cela, quand on joue avec le résultat
des fonctions getc() et compagnie, cela oblige à utiliser des int, les char
ne suffisent pas.
Si on ne caste pas, on risque d'avoir la mauvaise reponse pour 'ÿ' si char est signe.
Tu m'expliquera comment ton code permet d'éviter cela...
{ signed char c = EOF;
EOF peut parfaitement être inférieur à SCHAR_MIN... Imagine ce qui se passe s'il vaut -224
if (isprint(c)) { printf("%c is printablen", c); } else { printf("0xFF is not printablen");
Meilleur: printf("%#X is not printablen", c & UCHAR_MAX);
}
if (isprint((unsigned char)c)) {
Au secours ! Transtypage indéfini !
<résultat, coupé collé depuis plus bas:>
ÿ is printable
Merci d'apporter de l'eau à mon moulin. ;-). Tu stockes EOF dans c, et ton code, par la magie du transtypage, fait apparaître un 'ÿ' là où il n'y en a pas. C'est bien ce que je veux dénoncer. Et pour éviter cela, il faut _toujours_ utiliser int pour les variables caractères, pas char.
Merci d'avance pour le 'ÿ'!
Malheureusement c'est du vecu... On a eu un client hollandais qui avait un nom avec un ÿ.
D'abord, ton client, il devait avoir un nom en IJ, pas en ÿ (le ÿ, c'est pour des noms de famille français; mais comme en néerlandais IJ se trie à part, certains encodent ij avec ÿ, visuellement c'est acceptable, et hop !, le tri devient correct).
De plus, mon argument, c'est justement qu'il faut pouvoir encoder deux choses différentes: 'ÿ' et EOF. Et pour cela, quand on joue avec le résultat des fonctions getc() et compagnie, cela oblige à utiliser des int, les char ne suffisent pas.