Mailinglisten-Archive |
Hi, On Saturday 31 July 2004 16:43, Reinhold Jordan wrote: > naja, nur weil es geht, heißt es ja nicht, daß es auch > benutzt wird. In C/C++ gibt es auch ein goto - aber in > den letzten 16 Jahren habe ich nur ein Programm gesehen, > wo es auch benutzt wurde. Und de Menschen, der das > verbockt hat, würde ich kaum als Programmierer > bezeichnen... In meinem aktuellen Linux-Kernel-Source (2.6.5 + Gentoo-patches) habe ich 26426 mal das Pattern /goto [a-b_]+;/ innerhalb von .c Dateien gefunden.[^1] Wie ich schon schrieb setzt man goto zum Error-Handling ein. Damit ich mir hier jetzt kein (schlechtes) Beispiel erfinden muss mal ein Ausschnitt aus dem Linux-Kernel, genauer sound/usb/usbaudio.c (per Zufall ausgewählt, ein wenig gekürzt und ein wenig Einrückung entfernt, damit die Zeilen nicht zu lang werden) /* * set up and start data/sync urbs */ static int start_urbs(snd_usb_substream_t *subs, snd_pcm_runtime_t *runtime) { unsigned int i; int err; for (i = 0; i < subs->nurbs; i++) { snd_assert(subs->dataurb[i].urb, return -EINVAL); if (subs->ops.prepare(subs, runtime, subs->dataurb[i].urb) < 0) { snd_printk(KERN_ERR "cannot prepare datapipe for urb %d\n", i); goto __error; } } if (subs->syncpipe) { for (i = 0; i < SYNC_URBS; i++) { snd_assert(subs->syncurb[i].urb, return -EINVAL); if (subs->ops.prepare_sync(subs, runtime, subs->syncurb[i].urb) < 0) { snd_printk(KERN_ERR "cannot prepare syncpipe for urb %d\n", i); goto __error; } } } /*...*/ return 0; __error: // snd_pcm_stop(subs->pcm_substream, SNDRV_PCM_STATE_XRUN); deactivate_urbs(subs, 0, 0); return -EPIPE; } Nun was macht er? Spielt an seinen Substreams rum und wenn ein Fehler passiert, was an mehreren Stellen passieren kann, springt er mit goto ans Ende der Funktion und räumt auf. Was wären die Alternativen? - Den Aufräumcode in jede Stelle räumen wo es schief laufen kann und mit "return -EPIPE" aus der Funktion raus gehen - Eine Funktion raeum_auf() bauen und die Aufräum-Logik da rein und in komplexeren Situationen als oben alle Zeiger übergeben um den Speicher wieder freizugeben - Ein do { ... } while(0) Konstrukt bei dem im Fehlerfall ein break rausgeht und ansosnten am Ende des do-Blocks ein return 0 steht verwenden. Alles wohl nicht so schön und klar wie das goto - wenn es richtig verwendet wird. Nach dem Ausflug in die C-Welt zurück bei PHP ist dies weit weniger notwendig, da PHP den meisten Müll selber aufräumt (Stichwort: garbage collection) aber gelegentlich ist eigener Aufräumcode was schönes. Nun hat PHP5 Exceptions, mit denen kann man das auch machen, bloß wenn man mit PHP Prozedural programmiert - was ja durchaus erlaubt ist und immer mal wieder Sinn macht - ist es doch etwas fraglich für's Error-Handling plötzlich auf OO-Paradigmen zu setzen. Soweit mein Senf dazu, johannes [^1] Bevor es jetzt heißt "Jaja die Linux-Leute können eh nichts": Auch in dem Teil des Win2k-Sources der Microsoft abhanden gekommen ist gibt es Gotos... -- Johannes Schlüter php::bar | Der Treffpunkt für Einsteiger und Profis http://www.phpbar.de
php::bar PHP Wiki - Listenarchive