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..  
