?
[quote="Konfusius"]
Gotthard3 schrieb:
In deinem Falle ist if/else jedoch eindeutig besser
Wenn man deinen Code gescheit formatiert (mit indent -linux` '), sieht er so aus:
hHost CreatePortier(HostPhone MsgFunc)
{
if (ePortier != NULL || !MsgFunc)
return NULL;
if (!DLInit) {
if (!wsDLInit())
return NULL;
DLInit = 1;
}
if (ePortier = AllocPortier()) {
ePortier->myPort = PORTIER_PORT;
ePortier->OnRecv = MsgFunc;
ePortier->mySock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ePortier->mySock != INVALID_SOCKET) {
ePortier->OnRecv = MsgFunc;
if (BindPortier(PORTIER_PORT))
return ePortier;
closesocket(ePortier->mySock);
}
DeAllocPortier();
}
if (DLInit) // Dieses if ist unnötig
DLUnInit();
ePortier = NULL;
return NULL;
}
Ich finde das schlechter als mit goto, weil es eine Weile dauert, bis ich verstanden habe, dass alles nach return ePortier; Fehlerbehandlung ist und eigentlich gar nicht ausgeführt wird. Folgendes zeigt doch eindeutig, dass das ein Programmablauf ohne Verzweigungen ist und macht klar, was eigentlich ausgeführt werden sollte und was nicht:
hHost CreatePortier(HostPhone MsgFunc)
{
if (ePortier != NULL || !MsgFunc)
return NULL;
if (!DLInit) {
if (!wsDLInit())
return NULL;
DLInit = 1;
}
if (!(ePortier = AllocPortier()))
goto got_dl;
ePortier->myPort = PORTIER_PORT;
ePortier->OnRecv = MsgFunc;
ePortier->mySock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ePortier->mySock == INVALID_SOCKET)
goto got_portier;
ePortier->OnRecv = MsgFunc;
if (!BindPortier(PORTIER_PORT))
goto got_socket;
return ePortier;
got_socket:
closesocket(ePortier->mySock);
got_portier:
DeAllocPortier();
got_dl:
DLUnInit();
ePortier = NULL;
return NULL;
}
Für Fehlerbehandlung empfinde ich goto als das perfekte Werkzeug, hier soll es konsequent angewendet werden (selbst wenn nur ein einziges if nötig wäre), ansonsten nur noch um ein Mehrfachbreak nachzubauen.
Tricks wie bool-Flags finde ich total unnötig, weil umständlich in der Umsetzung/Nachvollziehbarkeit und langsamer als goto s.