Forum » Programiranje » [C] bug compilerja ali kaj drugega?
[C] bug compilerja ali kaj drugega?
ql000 ::
Hočem 2 8 bitni številki, ki sta zapisani vsaka v svojem delu polja zapisati v 16 bitni int. V DevC++ zadeva deluje tako:
Rezultat je 43775(10) oz. 1010101011111111(2). Vse v redu in prav. Vendar pa ista koda v C18 kompilerju (ta je za PIC mikrokontrolerje) ne deluje, razen, če znak += zamnejam z *=.
Kaj ta situacija bug znotraj nekega compilerja ali je to zgolj posebnost oz. odklon od ANSI standarda?
unsigned int cifra; unsigned char polje[2]; polje[1] = 255; polje[0] = 170; cifra = polje[0] << 8; cifra += polje[1]; printf(" Cifra: %d\n", cifra);
Rezultat je 43775(10) oz. 1010101011111111(2). Vse v redu in prav. Vendar pa ista koda v C18 kompilerju (ta je za PIC mikrokontrolerje) ne deluje, razen, če znak += zamnejam z *=.
Kaj ta situacija bug znotraj nekega compilerja ali je to zgolj posebnost oz. odklon od ANSI standarda?
y00r3 ::
Si ze slisal za union
Potem pa samo vneses podatke:
typedef union { unsigned int cifra; unsigned char polje[2]; } cifra;
Potem pa samo vneses podatke:
cifra a; a.polje[0] = 255; a.polje[1] = 170; printf(" Cifra:%d\n", a.cifra);Meni je do sedaj to delovalo brez problema.
Tutankhamun ::
A ti ta C18 prevajalnik nardi asemblersko kodo. Če ja, jo sm nalep, da se vid kasno kodo je naredu...
AMD Phenom QUAD 9950 Black Edition, 8GB
snow ::
Jaz navadno pri programiranju picov uporabim malo telovadbe z pointerji za takšne namene. Oziroma sem si napisal en define:
In potem dostopam do 16-bitne spremenljivke 'int a' v dveh delih BYTE(a,0) in BYTE(a,1). Predvsem uporabno ko pošiljam kaj preko uart.
Upam da sem oni define prav napisal, ker sem ga na pamet ;)
Se pa razume da je z union lepša rešitev...
#define BYTE(var,b) (((unsigned char *)(&var))+b)
In potem dostopam do 16-bitne spremenljivke 'int a' v dveh delih BYTE(a,0) in BYTE(a,1). Predvsem uporabno ko pošiljam kaj preko uart.
//oddajnik int a = 1234; send(BYTE(a,0)); send(BYTE(a,1)); //sprejemnik int a; BYTE(a,0)=recieve(); BYTE(a,1)=recieve();
Upam da sem oni define prav napisal, ker sem ga na pamet ;)
Se pa razume da je z union lepša rešitev...
Random mutation plus nonrandom cumulative natural selection - Richard Dawkins
snow ::
cifra = polje[0] << 8;
Je možno, da se tole C18 prevede zgolj v read&write (2 mov ukaza), brez brisanja spodnjih 8 bitov? Potem, bi teh osem bitov imelo neko neznano vrednost, kateri prišteješ nekaj (polje[1]).
Je možno, da se tole C18 prevede zgolj v read&write (2 mov ukaza), brez brisanja spodnjih 8 bitov? Potem, bi teh osem bitov imelo neko neznano vrednost, kateri prišteješ nekaj (polje[1]).
Random mutation plus nonrandom cumulative natural selection - Richard Dawkins
Matako ::
Sicer ne vem v čem je problem, žal, imaš pa še nekaj tukaj: v MingW (DevCPP) je unsigned int 32-biten, C18 bi utegnil imeti isti tip kot 16-bit int. Preveri tudi to, čeprav verjetno ni rešitev tvojega problema. To je čisto košer - velikost in tipov v C namenoma ni točno določena.
/\/\.K.
Zgodovina sprememb…
- spremenil: Matako ()
Gundolf ::
Noben hardware shift ne dela tako da pusti garbage v odshiftanih bitih snow. Če pa hardware nima shifta, potem pa mora C sam tole implementirat pravilno. Razen če je res res res zblojen C.
> Vendar pa ista koda v C18 kompilerju (ta je za PIC mikrokontrolerje) ne deluje, razen, če znak += zamnejam z *=.
Defniraj ta 'ne deluje'. Compiler error? Napačen rezultat? Podaj ta rezultat. Itd.
Union in pointerji imajo pa eno majhno pomankljivost - odvisni so od byte orderja.
Še ena ideja - a ti to dela tako kot da se shift sploh ne bi zgodil? Če se, potem poskusi popraviti tole:
cifra = ((unsigned int)polje[0]) << 8;
> Vendar pa ista koda v C18 kompilerju (ta je za PIC mikrokontrolerje) ne deluje, razen, če znak += zamnejam z *=.
Defniraj ta 'ne deluje'. Compiler error? Napačen rezultat? Podaj ta rezultat. Itd.
Union in pointerji imajo pa eno majhno pomankljivost - odvisni so od byte orderja.
Še ena ideja - a ti to dela tako kot da se shift sploh ne bi zgodil? Če se, potem poskusi popraviti tole:
cifra = ((unsigned int)polje[0]) << 8;
ql000 ::
Zadevo sem rešil z union-on. Zgleda, da je bila finta tudi pri: printf("%u\n", cifra).
Dejansko je bil totalno napačen rezultat, prevajalnik (C18) je enostavno seštel cifri 170 in 255, medtem, ko je pri isti kodi v DevC++ (MingW) rezultat v redu. Hec je tudi v tem, da se šift dejansko zgodi, kar sem preveril z tem, da sem se enkrat postavil na eno stran tega polja, sem šel enkrat desno, zamenjal stran in sem šel brat podatek na levo stran.
Problematičen je ta zadnji izraz -> cifra += polje[1]; Tam sem opazil, da mi se program zacikla. Od tiste točke ne gre naprej.
Ma moram še potipat Microchipov forum. Po mojem, ima prevajalnik prav svinski bug.
Defniraj ta 'ne deluje'. Compiler error? Napačen rezultat? Podaj ta rezultat. Itd.
Dejansko je bil totalno napačen rezultat, prevajalnik (C18) je enostavno seštel cifri 170 in 255, medtem, ko je pri isti kodi v DevC++ (MingW) rezultat v redu. Hec je tudi v tem, da se šift dejansko zgodi, kar sem preveril z tem, da sem se enkrat postavil na eno stran tega polja, sem šel enkrat desno, zamenjal stran in sem šel brat podatek na levo stran.
Problematičen je ta zadnji izraz -> cifra += polje[1]; Tam sem opazil, da mi se program zacikla. Od tiste točke ne gre naprej.
Ma moram še potipat Microchipov forum. Po mojem, ima prevajalnik prav svinski bug.
Zgodovina sprememb…
- spremenil: ql000 ()
Vredno ogleda ...
Tema | Ogledi | Zadnje sporočilo | |
---|---|---|---|
Tema | Ogledi | Zadnje sporočilo | |
» | [C++] Problem z knjižico?Oddelek: Programiranje | 901 (798) | black ice |
» | c grafikaOddelek: Programiranje | 993 (738) | aaaaa93 |
» | [C++] Kopiranje char arraya v drug char arrayOddelek: Programiranje | 1264 (1135) | win64 |
» | [C++] Kateri C++ IDE je najbolj osnoven?Oddelek: Programiranje | 2266 (1711) | sid_dabster |
» | [C++] prevajalnik hoce konstruktor za strukturoOddelek: Programiranje | 2586 (2290) | Tr0n |