OT odcitanie v C

Jan Waclawek konfera na efton.sk
Čtvrtek Duben 24 13:41:55 CEST 2014


>I kdy¾ udìlám závorky, výsledek 0xE2 je opravdu dost neoèekávaný.


Pochvala pred nastupenou jednotkou za rychle vyskusanie, bo neverim, ze ste
to dali z (bolavej) hlavy... ;-)


> Øádek
>  if ( ((uint16_t)l - h) < 3 ) result |= 2; je asi ten problém. Máte 
>nìjaké vysvìtlení ?


Najprv zopakujem dovod: do h sme akoze nacitali hodnotu citaca , ktory bol
v stave 0xFFFFFFFE, ale h je len uint16_t, takze v nom je 0xFFFE. Citac l
urobil 4 tiky a je v nom 0x00000002. Snazime sa urobit operaciu, ktorou
ziskame tych 4, t.j. < 3 musi byt false a < 10 musi byt true.

Ako prve sa robi to odcitanie, to ma po pretypovani l oba operandy
uint16_t, co je "menej ako" int (32-bitove, sme sa dohodli, t.j. znamienko
a 31 bitov), takze sa kvoli "usual conversions" oba operandy skonvertuju
do int (ich hodnota sa nezmeni) a urobi sa odcitanie. Vysledok odcitania
je 0xFFFF0004, ale pozor, typ je int, t.j. znamienkovy, t.j. sa to
interpretuje ako -0xFFFC, co je menej ako 3 (ktory ma implicitne tiez typ
int, ale je to kladna konstanta), co sme nechceli.

Mimochodom, vysledok odcitania vo vsetkych styroch pripadoch je 0xFFFF0004.
Rozdiel je v interpretacii a v "postprocesingu":

- v pripade (l - h), kedze l je uint32_t, co sa do int "nezmesti", h sa
konvertuje na uint32_t (a aj tie konstanty 3 a 10, ale kedze su male a
kladne, tak na tom nezalezi), takze sa porovnava celych 0xFFFF0004, a
zlyha to na porovnani voci 10

- v pripade ((uint16_t)l - h) ide o horepopisanu nechcenu konverziu na
znamienkovy int

- pripad (uint16_t)(l - h) v okamihu odcitania je rozdiel ako v prvom
pripade uint32_t, ale nasledne je explicitne konvertovany na uint16_t co z
neho zahodi hornych 16 bitov a ostane zelana hodnota 4; ta je pre ucely
porovnania implicitne konvertovana na int, ale je to kladna hodnota takze
na tom nezalezi

- pripad (uint16_t)((uint16_t)l - h) - v okamihu odcitania je rozdiel ako v
druhom pripade int, ale explicitna konverzia na uint16_t uplne rovnako
odreze hornych 16 bitov, takze ako v 3. pripade aj tu ostane zelana kladna
hodnota 4


wek




Další informace o konferenci Hw-list