Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Un exemple de cast utile sans pointeur

53 réponses
Avatar
Marc Boyer
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
--
Lying for having sex or lying for making war? Trust US presidents :-(

10 réponses

1 2 3 4 5
Avatar
Jean-Marc Bourguet
"Antoine Leca" writes:

En , Jean-Marc Bourguet va escriure:
Autre chose exemple (dans la veine unsigned):

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...


$ cat leca.c
#include <stdio.h>
#include <ctype.h>
#include <locale.h>

int main()
{
signed char c = EOF;

setlocale(LC_CTYPE, "");
if (isprint(c)) {
printf("%c is printablen", c);
} else {
printf("0xFF is not printablen");
}

if (isprint((unsigned char)c)) {
printf("%c is printablen", c);
} else {
printf("0xFF is not printablen");
}

if (isprint(EOF)) {
printf("EOF is printablen");
} else {
printf("EOF is not printablen");
}

return 0;
}
$ ~/soft/gcc-3.3/bin/gcc -Wall -W -ansi -pedantic-errors leca.c
$ ./a.out
0xFF is not printable
ÿ is printable
EOF is not printable

Merci d'avance pour le 'ÿ'!


Malheureusement c'est du vecu... On a eu un client hollandais qui
avait un nom avec un ÿ.

A+

--
Jean-Marc
FAQ de fclc: http://www.isty-info.uvsq.fr/~rumeau/fclc
Site de usenet-fr: http://www.usenet-fr.news.eu.org


Avatar
DINH Viêt Hoà

Donc, size_t, on attendra 15 jours avant de leur en
parler.


Tes élèves connaissent ce groupe de discussion ?
(Afin qu'ils voient comment tu prépares tes cours :) )

--
DINH Viêt Hoà

Avatar
DINH Viêt Hoà

Autre chose exemple (dans la veine unsigned):

char c;
if (isprint((unsigned char) c)) {

}


même problème avec l'utilisation de toupper()

--
DINH Viêt Hoà

Avatar
Marc Boyer
DINH Viêt Hoà wrote:
Donc, size_t, on attendra 15 jours avant de leur en
parler.


Tes élèves connaissent ce groupe de discussion ?
(Afin qu'ils voient comment tu prépares tes cours :) )


Certains oui. La première fois que je m'en suis apperçu,
ce fut un rien déstabilisant d'ailleurs.
Mais en fait je trouce ça bien.

Marc Boyer
--
Lying for having sex or lying for making war? Trust US presidents :-(


Avatar
Richard Delorme
Emmanuel Delahaye wrote:

In 'fr.comp.lang.c', Marc Boyer wrote:


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



Avatar
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 :-(



Avatar
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

Avatar
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




Avatar
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 :-(





Avatar
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



1 2 3 4 5