Buggfix Plus
Aktuellt datum och tid: 14.12 2018-09-20

Alla tidsangivelser är UTC + 1 timme




Svara på tråd  [ 145 inlägg ]  Gå till sida Föregående  1 ... 6, 7, 8, 9, 10  Nästa
Författare Meddelande
 Inläggsrubrik: Re: Enkla men fatala buggar
InläggPostat: 23.28 2014-08-15 
EF Sponsor
Användarvisningsbild

Blev medlem: 22.54 2006-09-23
Inlägg: 29977
Ort: Borås
Nja, håller inte med dig.
Det är inte fel att förklara vad koden gör, det blir oerhört mycket tydligare då, dessutom, så kan man faktiskt skilja mellan vad den bär göra och vad den gör.

Min devis, Kommentareran skall vara 10x Koden, typ, eller så.


Upp
 Profil  
 
 Inläggsrubrik: Re: Enkla men fatala buggar
InläggPostat: 06.29 2014-08-25 
Användarvisningsbild

Blev medlem: 08.24 2008-11-02
Inlägg: 453
Ort: Esbo, Finland
TomasL skrev:
Nja, håller inte med dig.
Det är inte fel att förklara vad koden gör, det blir oerhört mycket tydligare då, dessutom, så kan man faktiskt skilja mellan vad den bär göra och vad den gör.

Jag håller med, men det beror ju på vilken nivå du kommentarar vad koden gör.
Kommentarer som beskriver saker man uppenbart kan se från koden är bara överflödiga.

TomasL skrev:
Min devis, Kommentareran skall vara 10x Koden, typ, eller så.

Det låter alldeles för mycket, men beror givetvis på var kommentarerna är.
Om du har 10 rader kommentarer för varje rad kod, låter det väldigt jobbigt att läsa.
100 rader kommentarer för 10 rader kod kan vara ok, men låter fortfarande för mycket.
Om du måste skriva så mycket kommentarer för att beskriva koden du skriver,
borde du nog revidera din kod istället.


Upp
 Profil  
 
 Inläggsrubrik: Re: Enkla men fatala buggar
InläggPostat: 21.46 2014-08-28 
Användarvisningsbild

Blev medlem: 11.03 2007-09-10
Inlägg: 9074
Ort: Alingsås
Det handlar ju inte bara om kod eller kommentarer. Som stekern säger handlar det också om hur koden ser ut. Då tänker jag främst på hur den är organiserad, i form av funktioner, varibler med vettiga namn organiserade i struct:er och att man använder beskrivande MACRO (om man inte har någon princip om att aldrig använda MACRO).

Exempel på hur MACROn kan användas: Här säger MACROTs namn det man behöver veta
Kod: [Expandera/Minimera] [Hämta] (Untitled.txt)
  1. // analoga ingångar - ADC
  2.         #define AINP_temp   6 // Extern tempsensor mcp9700a som ger 500 mV vid noll grader plus 10 mV per grad C.
  3.         #define AINP_batt   7 // mäter 12-volten på ingången via 22k/10k spänningsdelare
  4.     // digitala utgångar          
  5.         #define FluidPumpOn()  PORTD |=  OUT_RELAY_1_VPUMP
  6.         #define FluidPumpOff() PORTD &= ~OUT_RELAY_1_VPUMP
  7.        
  8.         #define KontaktorOn()  PORTD |=  OUT_RELAY_0_KONTAKTORER
  9.         #define KontaktorOff() PORTD &= ~OUT_RELAY_0_KONTAKTORER
  10.        
  11.         #define LED_on()  PORTD |=  OUT_RELAY_3
  12.         #define LED_off() PORTD &= ~OUT_RELAY_3
  13.     // PWM-utgång 
  14.         #define SetPWM(val) OCR1A = (val) // 0-1023

Jag skulle aldrig skriva t.ex. PORTD &= ~(1 << PD5); direkt i koden. Antingen använder jag en funktion eller ett MACRO så det blir istället KontaktorOff(); - betydligt mer lättläst och mindre risk för småfel t.ex. ett tecken som kommit på fel ställe.

Exempel på struct: Jag vill gärna hålla variabelnamn korta utan att skapa obegripliga förkortningar. Kommentar obligatorisk för varje variabel.
Kod: [Expandera/Minimera] [Hämta] (Untitled.txt)
  1.    
  2.         typedef struct
  3.         {
  4.             /* inlästa rådata från ADC - filtreras under inläsning */
  5.             u16 raw_HV;     // driftbatteri spänning - ADC-data * 8 =  0-32767
  6.             s16 raw_curr;   // strömsensor read data - aDC-data * 8 = -32768 till +32767
  7.             u16 raw_batt;   // 12V system read data, 0-1023 * 4
  8.             u16 raw_temp;   // temperatur externt read data 0-1023 * 4
  9.             /* behandlade data från ADC */
  10.             u16 high_volt;  // driftbatteri spänning * 10 - t.ex. 130.0V = 1300
  11.             u16 batt_volt;  // 12V-batteri spänning * 100 - avläst 12.35 volt = 1235
  12.             s16 current;    // avläst ström från strömsensor * 100, t.ex. I = 24.55A = 2455
  13.             s16 temperatur; // temperatur externt - avläst = grader C * 10
  14.             s16 high_volt_temp_adjusted; //driftbatteri spänning * 10, justerad för teperatur.
  15.             s32 ampHours_fas1;  // antal inladdade amperetimmar * 10 << 16 , 2400<<16 = 240.0 Ah: totalt under fas1
  16.             s32 ampHours_fas2;  // antal inladdade amperetimmar * 10 << 16 , 2400<<16 = 240.0 Ah: totalt under fas2
  17.             s32 ampHours_diff;  // antal inladdade amperetimmar * 10 << 16 , 2400<<16 = 240.0 Ah: fas1 - fas2/0.15
  18.         } analogTyp;
  19.        
  20.         typedef struct
  21.         {
  22.             bo      AC_on;      // om nätspänning är ansluten
  23.             bo      ladd_run;   // styrning av laddare, på/av.
  24.             State   state;      // laddtillstånd
  25.             Orsak   stop_orsak;     // felkod
  26.             u16     time;       // tid i sekunder
  27.             u8      counter;    // räknar andra tider (sekunder)
  28.             s16     current_output; // laddarens utström, sätts med setLaddCurrent(nn)
  29.             u16     current_limit; // max strömgräns för laddare
  30.             u16     current_outlim; // utström begränsad
  31.             u16     fas1_volt_max; // omslag från Fas1 till fas2 - beroende av temperatur. U*10
  32.             u8      err_state;  // lagrar state vid error.
  33.             u16     err_time;   // lagrar tid vid "orsak", sekunder
  34.             u8      blink;      // antal blink med LED per sekund 0 - 15 * 16
  35.             bo      AC_off_Flag;// flagga som sätts om kontakten dragits ur under laddning eller efter laddning
  36.                
  37.         } systemTyp;
  38.                


Med rätt variablenamn och uppgifterna uppdelade i funktioner blir koden sedan lättläst:
Kod: [Expandera/Minimera] [Hämta] (Untitled.txt)
  1. /*** Analog read ***/
  2.    
  3.     analog.batt_volt = read12Vbatt();
  4.     analog.high_volt = readHighVolt();
  5.     analog.temperatur = readTemp();
  6.    


Upp
 Profil  
 
 Inläggsrubrik: Re: Enkla men fatala buggar
InläggPostat: 22.19 2014-08-28 
EF Sponsor
Användarvisningsbild

Blev medlem: 22.54 2006-09-23
Inlägg: 29977
Ort: Borås
Nu menar jag naturligtvis inte att man skall kommentera rader såsom A = B + C;, typ.
Dock skall det finnas förklarande texter vad Konstanterna är för något, Vad variablerna är (Oavsett snygga förklarande namn) samt vilka värden de förväntas anta osv, till detta kommer att förklara vad själva modulen gör samt vad respektive funktion gör och en kommentar i if/while/for satser om vad de gör och varför.

Det kvittar hur förklarander och tydlig koden är, efter ett halvår kommer man inte ihåg hur man tänkte, tyvärr.
Dessutom skall någon annan kunna göra nått, så är det bra för denne andra att veta hur tankarna gick.


Upp
 Profil  
 
 Inläggsrubrik: Re: Enkla men fatala buggar
InläggPostat: 22.30 2014-08-28 
EF Sponsor
Användarvisningsbild

Blev medlem: 22.54 2006-09-23
Inlägg: 29977
Ort: Borås
Citera:
Jag skulle aldrig skriva t.ex. PORTD &= ~(1 << PD5); direkt i koden. Antingen använder jag en funktion eller ett MACRO så det blir istället KontaktorOff(); - betydligt mer lättläst och mindre risk för småfel t.ex. ett tecken som kommit på fel ställe.

Det gör inte vi heller, vi enumrerar istället, då makron bara skapar problem, samt att vi även använder inversregistren och de biblioteksfunktioner som finns tillgängliga.
Så det kan till exempel bli PortSetBits(SPICSPort, ADC1); till exempel
Där SPICSPort och ADC1 är enumererade istället för #define'ade, typ.

Fördelen är ju att kompilatorn ger fel, om man klantar till det och försöker omdefiniera av misstag (Vilket är lätt hänt när kodmassan börjar närma sig någon halvmiljon rader), och med #define får man på sin höjd en varning, typ.


Upp
 Profil  
 
 Inläggsrubrik: Re: Enkla men fatala buggar
InläggPostat: 07.31 2014-08-29 
Användarvisningsbild

Blev medlem: 08.24 2008-11-02
Inlägg: 453
Ort: Esbo, Finland
TomasL skrev:
Det gör inte vi heller, vi enumrerar istället, då makron bara skapar problem [...]

enum är bra, men min mening är att de passar endast för konstanter i följande ordning.
Dvs, för t.ex. bit-definitioner eller adress-definitioner ser jag hellre en macro definition.
Kod: [Expandera/Minimera] [Hämta] (Untitled.txt)
#define SOMEPERIPHERAL_SOMEREGISTER_ADDR 0x10001000
#define SOMEPERIPHERAL_SOMEREGISTER_SOMEBIT (1<<5)

istället för
Kod: [Expandera/Minimera] [Hämta] (Untitled.txt)
enum {
  SOMEPERIPHERAL_SOMEREGISTER_ADDR = 0x10001000,
};
enum {
  SOMEPERIPHERAL_SOMEREGISTER_SOMEBIT = (1<<5),
};


Omdefinitioner undviks lättast genom att använda tillräckligt beskrivande namn,
om man har problem med att man lyckas använda samma namn på flera ställen,
så är det igen dags att titta över hur man skriver sin kod.

Sen det som Jesse sade om att mycket är beroende på hur koden ser ut och hur den är organiserad,
detta gäller inte bara kommentarer, utan även t.ex. variabelnamn.
Hur beskrivande ett variabelnamn behöver vara beror helt på vilket 'scope' (vad heter detta på svenska?)
variabeln har.
Ju större scope en variabel har, desto mer beskrivande behöver den vara och vice versa.
I min mening kan ner till enbokstavsvariabler vara helt ok när scopet är minimalt och meningen med dem är uppenbar.
Typexemplet är i,j,k för loop-variabler, men även andra fall kan inkluderas, t.ex. när variablen är av en typ där typen gör det uppenbart vad variabelns funktion är, t.ex.
Kod: [Expandera/Minimera] [Hämta] (Untitled.txt)
void init_device(struct device *d)
{
  d->reset_regs();
  d->bus->init();
  d->irq_init();
}


Upp
 Profil  
 
 Inläggsrubrik: Re: Enkla men fatala buggar
InläggPostat: 17.51 2015-09-27 
EF Sponsor
Användarvisningsbild

Blev medlem: 21.14 2006-07-31
Inlägg: 889
Ort: Österlen, Skåne
Google översätter scope med tillämpningsområde.
Stämmer ju bra i detta fall, men klumpigt tycker jag.


Upp
 Profil  
 
 Inläggsrubrik: Re: Enkla men fatala buggar
InläggPostat: 17.54 2015-09-27 
Användarvisningsbild

Blev medlem: 14.52 2005-01-10
Inlägg: 23067
Ort: Kristinehamn
I programmering anser jag att "scope" kan kallas "arbetsområde".


Upp
 Profil  
 
 Inläggsrubrik: Re: Enkla men fatala buggar
InläggPostat: 19.43 2015-10-30 

Blev medlem: 17.07 2013-06-01
Inlägg: 18
Jag föredrar det typsäkra:
Kod: [Expandera/Minimera] [Hämta] (Untitled.txt)
#include <stdint.h>
static const uint32_t SOMEPERIPHERAL_SOMEREGISTER_SOMEBIT = (1<<5);


och undviker funktionsmakron:
Kod: [Expandera/Minimera] [Hämta] (Untitled.txt)
static inline void KontaktorOn(void) {
  PORTD |=  OUT_RELAY_0_KONTAKTORER;
}


Onödigt att blanda in preprocessorn i onödan.


Upp
 Profil  
 
 Inläggsrubrik: Re: Enkla men fatala buggar
InläggPostat: 23.43 2016-06-29 
Användarvisningsbild

Blev medlem: 22.56 2008-11-27
Inlägg: 3094
Ort: Utanför Jönköping
Ingen bugg, bara avsaknad av databladsläsning...

SPI på en AVR: Använde gpio som CS. AVR är master. SS-pinnen är oanvänd ingång, flytande för tillfället. (ja jag vet, ska inte)
all SPI-kommunikation dör efter någon sekund, ibland mitt i en byte. Tydligen är SS-aktiv tillsammans med SPI
även i Master-mode, ifall man kör multimaster, om den dras låg anser AVR:en att nån annan vill prata på bussen och tvärtystnar.
Satte man SS till utgång funkade allt som det skulle :)


Upp
 Profil  
 
 Inläggsrubrik: Re: Enkla men fatala buggar
InläggPostat: 08.21 2016-09-23 
Användarvisningsbild

Blev medlem: 11.03 2007-09-10
Inlägg: 9074
Ort: Alingsås
Jag har en känska av arr den här tråden skulle passa bättre i "Programmering"....?

Anyway, här en kul sida med "månadens bugg", och lösningen på den, så klart.
"Lösningen" i det här fallet genereras av analysverktyget PC-lint.

Använder ni några kod-analys-verktyg , och vilka i så fall? Vilka tycker ni är bra / dåliga? Varför?

Bug of the Month Samples


Upp
 Profil  
 
 Inläggsrubrik: Re: Enkla men fatala buggar
InläggPostat: 09.41 2016-09-23 

Blev medlem: 22.28 2012-06-19
Inlägg: 1122
Ort: Linköping
Jag använder clangs statiska kodanalys ibland. Ganska bra faktiskt! Framförallt bra på att hitta vägar genom stora härken av switch-satser och preprocessor-defines som leder till odefinierade variabler etc.

Valgrind är bra också, men det är ju inte kodanalys utan runtime-test.


Upp
 Profil  
 
 Inläggsrubrik: Re: Enkla men fatala buggar
InläggPostat: 22.30 2017-03-01 
Användarvisningsbild

Blev medlem: 11.03 2007-09-10
Inlägg: 9074
Ort: Alingsås
Gjorde en 'bugg' idag som jag aldrig hade kommit på om jag inte råkade ha indata som utlöste buggen.

hur ofta skriver man inte t.ex. när man vill skriva ut en sträng (som inte är konstant):
Kod: [Expandera/Minimera] [Hämta] (Untitled.txt)
  1. char text[];
  2. ...
  3. printf(text);

DET ÄR FEL !

I mitt fall råkade strängen innehålla c-kod, och då blev det så här:

Original: sprintf( Buffer, " %2.2d", Tid.Sec );
Utskrift: sprintf( Buffer, " 1980043360", Tid.Sec ); :shock:

Det här var jag inte alls beredd på.... man måste alltså använda ett annat sätt att skicka ut informationen på... kanske printf("%s", text); ?

Hur många har gjort fel på den, räck upp en hand! :jimmyhacker:


Upp
 Profil  
 
 Inläggsrubrik: Re: Enkla men fatala buggar
InläggPostat: 22.34 2017-03-01 
Användarvisningsbild

Blev medlem: 07.13 2008-07-03
Inlägg: 13059
Ort: Norrköping
GCC varnar.


Upp
 Profil  
 
 Inläggsrubrik: Re: Enkla men fatala buggar
InläggPostat: 22.39 2017-03-01 
Användarvisningsbild

Blev medlem: 11.03 2007-09-10
Inlägg: 9074
Ort: Alingsås
inte min GCC:
Citera:
-------------- Build: Debug in wave (compiler: GNU GCC Compiler)---------------

mingw32-gcc.exe -Wall -g -c E:\CodeBlocks\filfix\main.c -o obj\Debug\main.o
mingw32-g++.exe -o bin\Debug\wave.exe obj\Debug\main.o
Output file is bin\Debug\wave.exe with size 32.80 KB
Process terminated with status 0 (0 minute(s), 0 second(s))
0 error(s), 0 warning(s) (0 minute(s), 0 second(s))



Upp
 Profil  
 
Visa inlägg nyare än:  Sortera efter  
Svara på tråd  [ 145 inlägg ]  Gå till sida Föregående  1 ... 6, 7, 8, 9, 10  Nästa

Alla tidsangivelser är UTC + 1 timme


Vilka är online

Användare som besöker denna kategori: RFC420 och 4 gäster


Du kan inte skapa nya trådar i denna kategori
Du kan inte svara på trådar i denna kategori
Du kan inte redigera dina inlägg i denna kategori
Du kan inte ta bort dina inlägg i denna kategori
Du kan inte bifoga filer i denna kategori

Sök efter:
Hoppa till:  
   
Drivs av phpBB® Forum Software © phpBB Group
Swedish translation by Peetra & phpBB Sweden © 2006-2010