Re: question C (You win)

Page principale

Répondre à ce message
Auteur: Laurent Vivier
Date:  
À: guilde
Sujet: Re: question C (You win)
Eric Cheminot wrote:
>
> Je crois que suivant les architectures et les compilos, le type char est signe
> ou non signe. Du coup l'affectation "c = -32" a une semantique plutot floue et
> les resultats le refletent....
>
> Conclusion : pour le portage, il faut faire hyper gaffe aux entiers en C !
>
> --
> Eric Cheminot
> Thesard LSR-SCOP
> 04 76 82 72 89


Gagne, si on utilise un "short", le compilo fait bien la conversion !!!

#include <stdio.h>

int main(int argc, char** argv)
{
        short c;


        c = -32;


        printf("%ld\n", (long)c);
}


AIX(PowerPC): -32

Ca se voit en assembleur ;-)

le diff est entre char et short est:

8,10c8,10
< 0x1000025c (main+0x1c) 386000e0        lil   r3,0xe0
< 0x10000260 (main+0x20) 98610038        stb   r3,0x38(r1)
< 0x10000264 (main+0x24) 88810038        lbz   r4,0x38(r1)
---

> 0x1000025c (main+0x1c) 3860ffe0        lil   r3,-32
> 0x10000260 (main+0x20) b0610038        sth   r3,0x38(r1)
> 0x10000264 (main+0x24) a8810038        lha   r4,0x38(r1)


r3 et r4 sont des registres 32 bits.

lil: load immediat long -> charge un entier long !!! (theoriquement le
signe ici n'a pas d'incidence sur la suite: on fait un "store" avec la
bonne taille ensuite)
stb: store byte -> stoque les 8 bits de poid faible du registre en
memoire
sth: store half-> stoque les 16 bits de poid faible du registre en
memoire

Et le probleme est en fait ici:

lbz: load byte and zero -> charge un octet dans un registre et mais les
24 bits restant a zero (pas d'extension de signe)
lha: load half algebraic -> charge un mot (16 bits) dans un registre et
copie le bit de signe dans les 16 bits restant.

Conclusion: char est effectivement non-signe !!!
(contrairement a tout les autres qui le sont par defaut)

A priori ca semble etre du a l'assembleur powerPC qui n'a pas
d'instruction de chargement d'octet avec recopie du bit de signe (pas
d'instruction "lba": load byte algebraic)

Sur AIX, rajoute "signed" devant char corrige le probleme mais genere du
code en plus !!!

< 0x10000264 (main+0x24) 88810038        lbz   r4,0x38(r1)
---

> 0x10000264 (main+0x24) 88610038        lbz   r3,0x38(r1)
> 0x10000268 (main+0x28) 5463c00e        sli   r3,r3,0x18
> 0x1000026c (main+0x2c) 7c64c670       srai   r4,r3,0x18  


sli: shift left immediat (decalage a gauche: on met le bit de signe au
bon endroit pour un long)
srai: Shift Right Algebraic Word Immediate (on recopie le bit de signe
dans les 24 restants)

Vu les resultats que m'a communique Olivier Aussage, ca doit etre la
meme chose sur SGI:

> OSF1 V4.0 878 alpha
> resultat: -32
>
> IRIX64 6.4 02121744 IP27
> resultat: 224
>
> HP-UX B.10.20 A 9000/819
> resultat: -32


Merci pour vos reponses !
A+
Laurent
-- 
=============== Laurent Vivier ==============
mailto:Laurent_Vivier@focal.fr        (FOCAL)
mailto:Laurent.Vivier@frec.bull.fr     (BULL)
mailto:Laurent.Vivier@capway.com      (PERSO)
---------------------------------------------
           UNIX is user-friendly...
It's just selective about who its friends are
---------------------------------------------