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

[TODO] vérifer et ajouter aux c traps

6 réponses
Avatar
rixed
l'opérateur ~, comme les autres, converti implicitement en int.
Donc :

unsigned short a = 0;
printf("%x\n", (unsigned)~a);

N'affichera pas 0xFFFF mais 0xFFFFFFFF (la convertion en unsigned int
est faite avant l'opérateur ~, et le cast en unsigned ne sert à rien).

6 réponses

Avatar
Targeur fou

l'opérateur ~, comme les autres, converti implicitement en int.
Donc :

unsigned short a = 0;
printf("%xn", (unsigned)~a);

N'affichera pas 0xFFFF mais 0xFFFFFFFF (la convertion en unsigned int
est faite avant l'opérateur ~, et le cast en unsigned ne sert à rien).


Non, ca affichera ffffffff, d'après le spécificateur de format x. Le
0x ou 0X s'affichera avec le drapeau #.

Pourquoi ne pas transtyper ~a en unsigned short, ou utiliser le
modificateur 'h' ?

#include <stdio.h>

int main(void)
{
unsigned short a = 0;
printf("%#x", (unsigned short)~a);
printf("%#hxn", ~a);
return 0;
}

A+

Avatar
Antoine Leca
En <news:42f78ed6$0$17702$, rixed va escriure:
l'opérateur ~, comme les autres, converti implicitement en int.


... si l'opérande est de taille inférieure (strictement).

Donc :


Groumpf! Je ne vois pas de lien logique clair entre la règle énoncée
ci-dessus et le résultat des deux lignes de codes ci-dessous.


unsigned short a = 0;
printf("%xn", (unsigned)~a);

N'affichera pas 0xFFFF mais 0xFFFFFFFF


Ah bon ?
Quelques résultats possibles :
ffff
ffffffff
fffffffff
ffffffffffffffff
0
ffffffffff
ffffffffffff
80000001 (avec un nombre variable de 0)

Bref, pas plus de 0xFFFFFFFF que de beurre en broche, comme l'explique
Régis, et en plus une série d'autres résultats possibles, certains auxquels
tu ne t'attendais certainement pas.


(la convertion en unsigned int est faite avant l'opérateur ~,


Non et non

et le cast en unsigned ne sert à rien).


Mouais. C'est vrai, mais probablement pas pour la raison à laquelle tu
penses : le spécificateur %x attend un unsigned int, donc si tu lui passes
un signed int (seule autre possibilité, comme tu l'explique plus ou moins)
il va faire lui même la conversion; donc effectivement le transtypage ne
sert à rien.

Mais :
1) ce transtypage caché est discuté par certains
2) il est de bon ton de passer les arguments avec les bons types
3) ajouter le transtypage ne change jamais le résultat et montre que tu as
analysé le problème


Antoine

Avatar
Cedric Cellier
Tiens, c'est drole, je me demandais où il était passé ce mail :-)

Normalement, les mails dont le sujet commencent par TODO atterrisent
dans une boite spéciale ; encore faut-il que je les poste pas par erreur
dans un forum. Heureusement, ce n'était pas complètement hors sujet.
Par contre, la rédaction est un peut trop personnelle :-)
Avatar
Cedric Cellier
Targeur fou wrote:


l'opérateur ~, comme les autres, converti implicitement en int.
Donc :

unsigned short a = 0;
printf("%xn", (unsigned)~a);

N'affichera pas 0xFFFF mais 0xFFFFFFFF (la convertion en unsigned int
est faite avant l'opérateur ~, et le cast en unsigned ne sert à rien).


Non, ca affichera ffffffff, d'après le spécificateur de format x. Le
0x ou 0X s'affichera avec le drapeau #.


Oui, certes, mais ce n'est pas ca qui m'interressait.
D'ailleurs dans le cas réel il n'y avait pas de printf : j'utilisais ~
sur un unsigned short que je castais ensuite en unsigned, persuadé que
j'aurais les 16 bits hauts (x86) à 0. C'était pour sommer des unsigned
short en complément à 1. Bref, je m'étais fait avoir par la conversion
implicite qui avait lieue avant l'inversion des bits. Je trouvais le
piège interressant, d'où le mail (adressé à moi même, croyais-je).
L'interret n'est pas dans le printf.


Avatar
Cedric Cellier
Cf réponse précédente : le printf est là pour la déco, ce n'est pas le
sujet du message (c'est pas clair parceque je croyais m'envoyer un mail
privé :-) roooooo, la grosse tâche... )


(la convertion en unsigned int est faite avant l'opérateur ~,


Non et non

et le cast en unsigned ne sert à rien).



Mouais. C'est vrai, mais probablement pas pour la raison à laquelle tu
penses :


Et à quoi je pense, grand medium ?

(réponse : à ca bien sur : http://www.popartuk.com/g/l/lg2564.jpg )


En fait, je trouvais piégant, quoique tout à fait naturel et souhaitable
après réflexion, qu'après le code suivant :

unsigned short a = 0;
unsigned short b = ((unsigned)~a)>>16;

... b valle 0xffff et pas 0.

Voilà, c'est tout.
Si vous trouvez ca évident c'est tant mieux, moi je m'y suis fait prendre.


Avatar
Antoine Leca
En <news:42fa7888$0$5472$,
Cedric Cellier va escriure:
Cf réponse précédente : le printf est là pour la déco, ce n'est pas le
sujet du message (c'est pas clair parceque je croyais m'envoyer un
mail privé :-) roooooo, la grosse tâche... )

et le cast en unsigned ne sert à rien).


Mouais. C'est vrai, mais probablement pas pour la raison à laquelle
tu penses :


Et à quoi je pense, grand medium ?


Je ne sais pas, mais je sais seulement que la raison que j'ai donnée n'est
PAS celle à laquelle tu pensais lorsque tu l'as écrit.
Enfin, « probablement », comme je l'écrivis (parce que si tu savais bien que
le (unsigned) ne servait à rien dans le contexte à savoir printf avec
conversion %u, alors même que le « printf n'est là que pour la décoration »,
bin je trouve tes raisonnements un poil alambiqués).

Quant au qualificatif, si nos élucubrations sur tes élucubrations ne
t'intéressent pas...


En fait, je trouvais piégant, quoique tout à fait naturel et
souhaitable après réflexion, qu'après le code suivant :

unsigned short a = 0;
unsigned short b = ((unsigned)~a)>>16;

... b valle 0xffff et pas 0.


Cf. mon message précédent pour d'autres valeurs possibles pour b.


Voilà, c'est tout.
Si vous trouvez ca évident c'est tant mieux, moi je m'y suis fait
prendre.


Non, ce n'est pas « évident » et il est effectivement facile de se faire
prendre.
De fait, il faut bien voir qu'en C, les short sont des types de seconde
zone, les véritables opérations utilisent au premier chef les int et ensuite
les char ou les long. Quand bien même l'architecture du processeur que tu
utilises permets de faire autrement. C'est le résultat de l'évolution du
langage (je pense qu'avec Pascal ou Ada tu aurais des résultats plus «
logiques », mais l'évolution fut différente même si le résultat est
globalement comparable).


Antoine