2009-05-18, 10:25
  #1
Medlem
Ergodynes avatar
En lite fråga vad ni tycker om att använda goto när man skriver c++

Jag fick alltid lära mig att man aldrig aldrig aldrig ska använda goto när man skriver c eller framförallt c++. Men på senare tid har jag stött på kod som använder det ganska flitigt.

Skillnaden är iofs att dessa goto-satser inte hoppar runt i programmet så mycket utan snarare ser till att man flyttar sig förbi vissa rader bara.

Följande är ett exempel på hur en kodsnutt kan se ut:

[PHP]
int SomeFunction(int parameter)
{
int retVal = FALSE;

if (!Initiate())
goto ERROR_END;

if (!AllocateMemory())
goto ERROR_END;

if (!RunAnalysis())
goto ERROR_END;

return TRUE;

ERROR_END:

ReleaseMemory();
return FALSE;

}
[/PHP]

Skulle man skriva detta med if-satser så blir det ju mycket mer nästlat och antag att man gör ännu fler kontroller så skulle det till slut bli oläsbart.

Så kan man i detta fall tycka att det är ok att använda goto?
Citera
2009-05-18, 10:30
  #2
Medlem
IRMEs avatar
Det blir ju typ två rader mer, utan goto? Men ja, använd den hur mycket du vill så länge folk kan förstå din kod och att du dokumenterar effektivt. Frågan är väl hur snabb den är om man pratar riktig optimering Då kanske if-satser är betydligt snabbare.
Citera
2009-05-18, 10:52
  #3
Medlem
micaeles avatar
Det finns självklart fall då goto är en vettig och nödvändig lösning, men man skall alltid tänka kritiskt till användningen av detta.
Citera
2009-05-18, 10:56
  #4
Medlem
http://xkcd.com/292/
Citera
2009-05-18, 10:57
  #5
Medlem
micaeles avatar
Citat:
Ursprungligen postat av SixtenSune
http://xkcd.com/292/
Ungefär så ska man tänka när man använder goto, ja. Men alla undantag har regler, som vi vet. Ful kod kräver fula lösningar...
Citera
2009-05-18, 12:04
  #6
Medlem
Exemplet är ju lite haltande, men budskapet går fram. Det där pratet om att aldrig avända goto är ju bara en sådan där sak som dåliga akademiker upprepar som ett mantra för att de inte kan tänka själva.

Jag uppmanar alla goto-hatare att vara konsekventa och avsäga sig följande konstruktioner:

* switch
* loopar
* break
* continue
* if
* funktionsanrop
* return

för allt det där hoppar ju fram och tillbaka, hit och dit, så man blir alldeles yr!
Citera
2009-05-18, 12:50
  #7
Medlem
Strikta regler om vad man aldrig och alltid ska göra är väl på det hela taget en ganska dålig ide. Starka rekommendationer är en annan sak. Dom finns förmodligen av en anledning.

Med det sagt har jag aldrig upplevt att det skulle passa med ett goto. Men är det den bästa lösningen så är det. Se upp för veliociraptorer dock.
Citera
2009-05-18, 13:13
  #8
Medlem
Weeblies avatar
Exemplet du nämnde är ett klassiskt sådant som involverar goto och som är accepterat av i princip alla professionella C programmerare (såvidda dem inte råkar vara goto-hatare). Du hittar liknande konstruktioner i bland annat FreeBSD's källkod.

Beroende på vilken paradigm man följer så behöver man nödvändigtvis inte använda denna konstruktion i C++. Följer man RAII från start till slut så ger konstruktorer/destruktorer/exceptions ungefär samma effekt.
Citera
2009-05-18, 22:00
  #9
Medlem
Som nämndes här innan så är ju en av de snyggaste sakerna med C++ att man kan fixa cleanup och minneshantering med att ha variabler på stacken och hantera exceptions.

Alltså, tanken är typ att man så långt som möjligt har all minneshantering antingen så att saker bara är medlemsvariabler, eller om det måste bli heap-minne med new(), så görs det i en konstruktur för ett objekt och delete() görs i destruktorn.

Sedan när objektet går ur scope, så körs automatiskt delete (och eventuella andra resurser släpps också). T.ex. gör man snyggt samma sak genom att ta tråd-lås genom att skapa dom i en konstruktor och släppa i en destruktor. Sen i början av sin funktion som kräver ett lås så skapar man ett "ta låset"-objekt som en vanlig variabel (inte med new()). Sedan när man returnerar från funktionen så släpps låset automatiskt. På så vis så försvinner liksom skälet att göra som i goto-exemplet här. Alla resurser släpps när objektet går ur scope.

På samma sätt så städas dom snyggt bort om något slänger ett exception. Det fixar nog inte goton?
Citera
2009-05-19, 00:02
  #10
Medlem
fittPlusPluss avatar
Citat:
Skulle man skriva detta med if-satser så blir det ju mycket mer nästlat och antag att man gör ännu fler kontroller så skulle det till slut bli oläsbart.

hmm koden nedan gör väl exakt samma sak som din kod snutt? tycker isåfall den är lite enklare att läsa...eller?

[PHP]
int SomeFunction(int parameter)
{
int retVal = FALSE;

if (!Initiate() || !AllocateMemory() || !RunAnalysis())
{
ReleaseMemory();
return false;
}

return true;
}
[/PHP]
Citera
2009-05-19, 00:44
  #11
Medlem
Banshee19s avatar
Jag fattar inte riktigt grejen, kan man inte bara ersätta goto med ett funktionsanrop till den funktion man goto:ar till? Eller är jag lite tokig nu?
Citera
2009-05-19, 01:25
  #12
Medlem
Rimligare i goto-land kan vara att ha något i den här stilen:
Kod:
int SomeFunction()
{
	int retVal = FALSE;

	if (!func_A())
		goto A;

	if (!func_B())
		goto B;

	if (!func_C())
		goto C;

	retVal = TRUE;

C:
             undo_C();
B:
             undo_B();
A:
             undo_A();

	return retVal;
	
}
Citera
  • 1
  • 2

Skapa ett konto eller logga in för att kommentera

Du måste vara medlem för att kunna kommentera

Skapa ett konto

Det är enkelt att registrera ett nytt konto

Bli medlem

Logga in

Har du redan ett konto? Logga in här

Logga in