Sida 6 av 11
Re: Enkla men fatala buggar
Postat: 8 oktober 2013, 20:47:08
av blueint
När skillnad i precedens saknas skall det evalueras från vänster till höger.
Det svåra är väl att tänka igenom uttrycken och att en del kompilatorer inte följer standard. En genväg är då att använda explicita paranteser för att tvinga igenom precedens. Men det kan bli många paranteser..
Re: Enkla men fatala buggar
Postat: 8 oktober 2013, 21:05:32
av TomasL
Nja, det finns inget krav i C-standarden om det, vill jag minnas, utan är plattforms/kompilator beroende.
K&R skrev:The moral is that writing code that depends on order of evaluation is bad programming practice in any language
Ta till exempel
F kan evalueras före g eller viceversa, så om då en av funktionerna påverkar variabler som används i den andra, kan vad som helst hända.
Samma gäller till exempel:
Kod: Markera allt
printf ( "%d %D\n", ++n, power(2,n));
a[i] = i++;
Ovanstående två exempel ger vilt skilda resultat beroende på kompilatorn, och kan faktiskt ge olika resultat mpå samma kompilator, vid två påföljande kompileringar.
Re: Enkla men fatala buggar
Postat: 8 oktober 2013, 23:00:20
av blueint
Följer program inte specifikationer så kan vad som helst hända..

Re: Enkla men fatala buggar
Postat: 8 oktober 2013, 23:46:13
av TomasL
Vilka specifikationer?
Re: Enkla men fatala buggar
Postat: 9 oktober 2013, 00:30:04
av jesse
blueint skrev:Följer program inte specifikationer så kan vad som helst hända..

Följer man inte goda råd så kan vad som helst hända.... t.ex. att man struntar i att använda parenteser.
Re: Enkla men fatala buggar
Postat: 9 oktober 2013, 00:33:56
av blueint
C89, C90, C99, C11 osv. Man kan förstås välja att inte följa dessa. Men då får skaparen av kompilatorn vara tydlig med detta.
Re: Enkla men fatala buggar
Postat: 9 oktober 2013, 01:50:02
av sodjan
Problemet är när specen säger "unspecified" eller "undefined".
Re: Enkla men fatala buggar
Postat: 9 oktober 2013, 07:20:55
av Andax
Oavsett om man följer standarden eller inte så är det dålig programmering att inte vara tydlig i vad som görs. Så kör man utan parenteser anser jag att koden är ofullständig och dålig.
Re: Enkla men fatala buggar
Postat: 9 oktober 2013, 07:23:16
av blueint
Står det "unspecified" eller "undefined" så kör man stenhårt med paranteser. Kanske man t.om slänger in en enkel funktion som kontrollerar att kompilatorn gör rätt.
Re: Enkla men fatala buggar
Postat: 9 oktober 2013, 08:22:50
av superx
I de fallen jag kommer att tänka på där det är odefinierat (som i TomasLs exempel) så hjälper det inte med parenteser. Men det kanske finns sådana fall också?
Re: Enkla men fatala buggar
Postat: 9 oktober 2013, 08:51:21
av blueint
Om det inte hjälper att t.ex göra om:
printf ( "%d %D\n", ++n, power(2,n));
Till:
n++;
printf ( "%d %D\n", n, power(2,n));
Eller t.om:
n++;
pw = power(2,n);
printf ( "%d %D\n", n, pw);
Samt "low = input & 0x0F << 4" till "low = (input & 0x0F) << 4" då är det illa!

Re: Enkla men fatala buggar
Postat: 9 oktober 2013, 09:05:44
av TomasL
De exemplen jag visade måste delas upp så att man använder mellanresultat, för att få korrekt funktion på det hela och i den oordningen man vill ha det.
Generellt gäller dock alltid parenteser och ofta mellanresultat (vilka naturligtvis är enklare att debugga).
Re: Enkla men fatala buggar
Postat: 9 oktober 2013, 09:05:53
av bit96
blueint:
Självklart skall det skrivas om, men kanske inte på det sätt du föreslår.
Det beror på om programmeraren vill använda det 'gamla' eller 'nya' värdet på 'n' vid anrop av power().
Och det vet bara denne (förhoppningsvis). Och eftersom det saknas kommentarer så kan ingen veta hur det skall vara.
Det enda vi kan säga är att resultatet inte är entydigt.
Vid funktionsanrop kan argumenten beräknas i valfri ordning (kompilatorberoende) enligt standard.
Just därför kan/skall man inte både beräkna och använda en variabel flera gånger i ett funktionsanrop.
Re: Enkla men fatala buggar
Postat: 9 oktober 2013, 09:18:18
av bit96
TomasL skrev:
Ta till exempel
F kan evalueras före g eller viceversa, så om då en av funktionerna påverkar variabler som används i den andra, kan vad som helst hända.
T.ex. kan man skriva:
Kod: Markera allt
float X, f_del, g_del; /* xxx-funktionernas summa samt del-resultat */
...
/* Beräkna delresultaten från ggg och fff. OBS! g() måste beräknas först eftersom vissa globala variabler påverkas som f() behöver */
g_del=g():
f_del=f();
X=f_del+g_del; /* Summan av ggg och fff är klar. Även de globala variablerna har uppdaterats */
Då har man kommenterat vad som händer, sett till att slutsumma och delresultat har samma cast, samt förklarat att globala variabler används.
Förhoppningsvis är kodsnutten tolkningsbar för näste programmerare om 18 månader.
Dessutom ger den förhoppningsvis samma resultat även om kompilator ändras eller byts till annat fabrikat.
Re: Enkla men fatala buggar
Postat: 9 oktober 2013, 09:22:32
av blueint
Glabala variabler och sidoeffekter är rena minfältet..
