29 Stimmen

Warum hat dieser Code noch funktioniert?

Ein alter Code, auf den ich gerade gestoßen bin:

MLIST * new_mlist_link()
{
    MLIST *new_link = (MLIST * ) malloc(sizeof(MLIST));
    new_link->next  = NULL;
    new_link->mapi  = NULL;
    new_link->result = 0;
}

Dies wurde aufgerufen, um eine verkettete Liste zu erstellen, aber ich habe bemerkt, dass es keine Anweisung gibt:

return new_link;

Auch ohne die Rückgabeanweisung wurde die Liste dennoch richtig erstellt. Warum ist das passiert?

Bearbeitung: Plattform: Mandriva 2009 64bit Linux 2.6.24.7-server GCC 4.2.3-6mnb1

Bearbeitung: Lustig... dieser Code lief auch erfolgreich auf etwa 5 verschiedenen Linux-Installationen, alle unterschiedliche Versionen/Varianten, sowie auf einem Mac.

1voto

Daniel Punkte 870

Am wahrscheinlichsten ist es, dass es einen sehr schwer zu findenden Fehler erzeugen wird. Ich bin mir nicht sicher, wo ich es gelesen habe, aber ich erinnere mich, dass die meisten Compiler standardmäßig zu void zurückkehren, wenn Sie vergessen, eine return-Anweisung einzufügen.

Hier ist ein kurzes Beispiel:

#include 

using namespace std;

int* getVal();

int main()
{
        int *v = getVal();
        cout << "Wert ist: " << *v << endl;
        return 0;
}

int* getVal()
{
        // hier nichts zurückgeben
}

Für mich funktioniert das auch. Wenn ich es jedoch ausführe, erhalte ich ein Segmentfehler. Es ist also wirklich undefiniert. Nur weil es sich kompiliert, heißt das nicht, dass es funktioniert.

0voto

James Morris Punkte 4749

Es funktioniert, weil in den 1940er Jahren, als die C-Sprache erstellt wurde, kein Rückgabe Schlüsselwort existierte. Wenn Sie im "Funktionen" Abschnitt des C43 MINSI Standards nachschauen, steht dort folgendes zum Thema (unter anderem):

16.4.3b Für die Abwärtskompatibilität MUSS das EAX-Register verwendet werden, um
        die Adresse des ersten Speicherbereichs zurückzugeben, der von malloc allokiert wurde.

-1voto

Nathan Osman Punkte 67377

Möglicherweise ein Zufall:

Der Speicherplatz für den Rückgabewert der Funktion wird im Voraus allokiert. Da dieser Wert nicht initialisiert ist, könnte er auf den gleichen Speicherplatz im Heap zeigen wie der für das Struct allokierte Speicher.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X