Vad i helsike händer, IF-sats funkar inte

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 45270
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Vad i helsike händer, IF-sats funkar inte

Inlägg av TomasL »

I följande kod:

Kod: Markera allt

typedef enum {PUMP_FOLLOW=0, PUMP_ON} Pump_drift_enum;
Pump_drift_enum KB_Pump_varmedrift_e;
där
"KB_Pump_varmedrift_e" är satt till "PUMP_FOLLOW"
följande kod funkar INTE (dvs IF'en är falsk)

Kod: Markera allt

if(global_inst.KB_Pump_varmedrift_e == PUMP_FOLLOW) {
ej heller

Kod: Markera allt

if(global_inst.KB_Pump_varmedrift_e == 0) {
däremot funkar följande

Kod: Markera allt

debug = global_inst.KB_Pump_varmedrift_e;
if(debug == PUMP_FOLLOW) {
Vad i jösse namn är det som händer.
Ickefungerande assembler ser ut så här:

Kod: Markera allt

205:                 			if(global_inst.KB_Pump_varmedrift_e == 0) {
9D068F34  3C02A000   lui         v0,0xa000
9D068F38  244215E0   addiu       v0,v0,5600
9D068F3C  8C42084C   lw          v0,2124(v0)
9D068F40  14400008   bne         v0,zero,0x9d068f64
9D068F44  00000000   nop 
Fungerande

Kod: Markera allt

202:                 	debug = global_inst.KB_Pump_varmedrift_e;
9D068EFC  3C02A000   lui         v0,0xa000
9D068F00  244215E0   addiu       v0,v0,5600
9D068F04  8C42084C   lw          v0,2124(v0)
9D068F08  A7C20024   sh          v0,36(s8)

206:                 			if(debug == PUMP_FOLLOW) {
9D068F24  97C20024   lhu         v0,36(s8)
9D068F28  14400008   bne         v0,zero,0x9d068f4c
9D068F2C  00000000   nop        
Har inte tagit med all kod i assemblerlistningarna, enbart den som är relevant i If-arna
Processor PIC32MX695, MPLAB IDE (ej MPLAB-X)
Language tool versions: pic32-ar.exe v2.02, pic32-gcc.exe v2.02, pic32-ld.exe v2.02, pic32-ar.exe v2.02
Användarvisningsbild
Klas-Kenny
Inlägg: 11327
Blev medlem: 17 maj 2010, 19:06:14
Ort: Växjö/Alvesta

Re: Vad i helsike händer, IF-sats funkar inte

Inlägg av Klas-Kenny »

Vad säger debuggern om du stoppar på if'en i de båda fallen?

Edit: Hur är global_inst deklarerad?
Hur blir KB_Pump_varmedrift_e plötsligt medlem i den?
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 45270
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: Vad i helsike händer, IF-sats funkar inte, [LÖST]

Inlägg av TomasL »

Så nu hittade vi felet, en liten slamkrypare.

Det visade sig att en enum i PIC32/MIPS/GCC-världen är en 32bitars variabel.
Vårt menysystem sparade bara ned de lägre 16 bitarna, samt att variabeln i fråga inte var initierad.
Detta sammantaget gjorde att de övre 16 bitarna i variabeln läste skräp, vilket gjorde att det inte funkade.
Eftersom inställningsvärdet, lagras i ett SPI-minne, så var det bara att skriva om minnet med alla 32 bitar.
Därefter funkar det som tänkt är.

Dock får vi nog fundera på hur vi skall validera det hela, eftersom vår menygenerator enbart genererar 16-bitars tal.
hummel
Inlägg: 2267
Blev medlem: 28 november 2009, 10:40:52
Ort: Stockholm

Re: Vad i helsike händer, IF-sats funkar inte

Inlägg av hummel »

Casting, har du alla varningar, lint osv påslaget i kompilatorn? Du bör få en varning om detta.
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 45270
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: Vad i helsike händer, IF-sats funkar inte

Inlägg av TomasL »

GCC ger inga varningar trots att allt skall vara påslaget.
-g -Wparentheses -fno-builtin -funsigned-char -Wall -Wno-pointer-sign
hummel
Inlägg: 2267
Blev medlem: 28 november 2009, 10:40:52
Ort: Stockholm

Re: Vad i helsike händer, IF-sats funkar inte

Inlägg av hummel »

Det borde väl räcka, om jag minns rätt. Har du PC-Lint, den plockar mycket dumheter.
Användarvisningsbild
baron3d
EF Sponsor
Inlägg: 1339
Blev medlem: 1 oktober 2005, 23:58:43
Ort: Torestorp

Re: Vad i helsike händer, IF-sats funkar inte

Inlägg av baron3d »

Går det att ändra storleken på enum i GCC ?

Skulle också vara bra att få en varning på oinitierade variabler.
SvenW
Inlägg: 1122
Blev medlem: 24 april 2007, 16:23:10
Ort: Göteborg

Re: Vad i helsike händer, IF-sats funkar inte

Inlägg av SvenW »

> Oinitierade variabler:
Det går med valgrind. Osäker på om den fungerar med småprocessorer.
Användarvisningsbild
lillahuset
Gått bort
Inlägg: 13969
Blev medlem: 3 juli 2008, 08:13:14
Ort: Norrköping

Re: Vad i helsike händer, IF-sats funkar inte

Inlägg av lillahuset »

Knappast på en PIC32 utan OS.
Användarvisningsbild
baron3d
EF Sponsor
Inlägg: 1339
Blev medlem: 1 oktober 2005, 23:58:43
Ort: Torestorp

Re: Vad i helsike händer, IF-sats funkar inte

Inlägg av baron3d »

Angående enum's storlek.

Bästa packning får man med "-fshort-enums"
Detta fungerar bra på egen kod lika säkert som rysk roulette.

Bättre är att använda "__attribute__ ((packed))", men fortfarande lite slumpmässigt beteende.

Ser man till att minst ett värde är större än 255 så blir det 2 bytes.
t.ex.

Kod: Markera allt

typedef enum {NOT_INVERTED=0, INVERTED=1000} __attribute__ ((packed)) inverted_enum;
Vilket fungerar bra! :)
Användarvisningsbild
Icecap
Inlägg: 26139
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: Vad i helsike händer, IF-sats funkar inte

Inlägg av Icecap »

baron3d: nu var problemet att variabeln var en 16 bitars men enum-värdet var 32 bitars...
Så att deklarera som packed lär inte göra något alls i det problem.

Grundproblemet verkar vara att det inte säkert kan deklareras vilken storlek en enum-variabel har.
"typedef enum {PUMP_FOLLOW=0, PUMP_ON} Pump_drift_enum;" anger ju att Pump_drift_enum är av typen "enum" och den är helt klart i TomasL's fall en int.

Om sedan "-fshort-enums" faktisk ställer default enum till att vara short är det ju lösningen.
Användarvisningsbild
Andax
Inlägg: 4373
Blev medlem: 4 juli 2005, 23:27:38
Ort: Jönköping

Re: Vad i helsike händer, IF-sats funkar inte

Inlägg av Andax »

Fast om det inte är en bugg i kompilatorn borde den klaga/varna när man tilldelar ett 32-bitarsvärde till en 16-bitars variabel...
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 45270
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: Vad i helsike händer, IF-sats funkar inte

Inlägg av TomasL »

så här skriver GCC om -fshort-enums
Allocate to an enum type only as many bytes as it needs for the declared range of possible values. Specifically, the enum type will be equivalent to the smallest integer type which has enough room.
Så om jag fattar det rätt:
enum {zero, one, two};
Så blir det en int (32 bitar på pic32), som standard.

Med ovan nämda kompilatordirektiv så skall det bli en char (8 bitar) istället.
Eller har jag fattat det fel?

Andax, ja, man kan tycka att kompilatorn skall varna för att den gör en cast.
Dock i IFen så görs ju ingen cast, eller nånting.
När variabeln lagras så görs en cast, typ eller nånting.
Användarvisningsbild
Icecap
Inlägg: 26139
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: Vad i helsike händer, IF-sats funkar inte

Inlägg av Icecap »

Så lärdomen är att närhelst man använder enum-värden SKA man casta dom alltid.
Användarvisningsbild
lillahuset
Gått bort
Inlägg: 13969
Blev medlem: 3 juli 2008, 08:13:14
Ort: Norrköping

Re: Vad i helsike händer, IF-sats funkar inte

Inlägg av lillahuset »

Är inte lärdomen snarare att om man envisas med enum ska man aldrig blanda dem med numeriska värden även om man "vet" vad varje enum ska ha för värde.
Felet här är väl att menysystemet returnerar numeriska värden som sedan hanteras som enum. Där kanske kompilatorn skulle ha gett felmeddelande.

Edit: Och en cast är, om man ska vara petig, alltid en öppning för fel i programmet. Jo jag använder ändå castar ganska ofta men i stort sett aldrig enum. Fy på mig. :)
Skriv svar