Warum NULL von main () zurückgeben?

10

Ich sehe manchmal Codierer, die NULLals Rückgabewert von main()in C- und C ++ - Programmen verwendet werden, zum Beispiel so etwas:

#include <stdio.h>

int main()
{
    printf("HelloWorld!");

    return NULL;
} 

Wenn ich diesen Code mit gcc kompiliere, erhalte ich die Warnung:

Warnung: return macht eine Ganzzahl vom Zeiger ohne Umwandlung [-Wint-Konvertierung]

Dies ist sinnvoll, da das Makro NULLerweitert werden soll (void*) 0und der Rückgabewert von main vom Typ sein soll int.

Wenn ich ein kurzes C ++ - Programm mache aus:

#include <iostream>
using namespace std;

int main()
{
    cout << "HelloWorld!";

    return NULL;
}

Und kompiliere es mit g ++, ich bekomme eine gleichwertige Warnung:

Warnung: Konvertierung von NULL in den Nicht-Zeigertyp 'int' [-Wconversion-null]

Aber warum verwenden sie NULLals Rückgabewert, main()wenn eine Warnung ausgegeben wird? Ist es nur ein schlechter Codierungsstil?


  • Was ist der Grund, trotz der Warnung NULLanstelle des 0Rückgabewerts zu verwenden main()?
  • Ist die Implementierung definiert, ob dies angemessen ist oder nicht, und wenn ja, warum sollte eine Implementierung einen Zeigerwert zurückerhalten wollen?
RobertS unterstützt Monica Cellio
quelle
4
Sie sollten sie direkt fragen.
Juanchopanza
5
"Warum verwenden sie NULL als Rückgabewert von main ()" - das tun wir nicht. Der Autor dieses Codes tut dies. Ich würde gerne ihren Versuch hören, zu rechtfertigen, warum.
WhozCraig
1
@Vlad aus Moskau ja, aber ich musste überprüfen, ob es wirklich 0 war. ^^ - EXIT_FAILUREist 8, und es scheint, dass die Verwendung von 1 nicht gut für einen Fehler ist, da es manchmal in einigen Programmen als Erfolg verwendet wird.
Waelmio
2
@RobertSsupportsMonicaCellio Wenn das wirklich die Antwort war, die du bekommen hast, ist das irgendwie traurig. Erstens macht es keinen Sinn (wäre sinnvoller, wenn es eher überall als irgendwo wäre ). Zweitens ist es ein Ausverkauf. Wenn Sie Code schreiben, sollten Sie einen guten Kompass haben, um festzustellen, ob er korrekt ist. nicht einfach mitmachen, denn so scheint es von ... jemandem gemacht zu werden. Sie scheinen diese Nadel in die richtige Richtung zu zeigen (also warum fragen Sie); Nicht so sehr die Person, die diesen Code geschrieben hat, sondern Ihnen diese Antwort als Grund dafür gegeben hat.
WhozCraig
2
In c ist es vollkommen gültig, den NULLZeiger als 0(ohne Umwandlung in void *) zu definieren . In diesem Fall bleibt der Fehler unbemerkt und generiert keine Warnung. Es ist immer noch nicht das, wofür NULL verwendet werden sollte.
Ctx

Antworten:

14

das ist vernünftig

Ja.

weil das Makro NULLauf erweitert werden soll(void*) 0

Nein. In C ++ NULL darf das Makro nicht auf (void*) 0[support.types.nullptr] erweitert werden. Dies kann nur in C geschehen.

In beiden Fällen ist das Schreiben von Code wie diesem irreführend, da NULLer sich auf die Nullzeigerkonstante beziehen soll , unabhängig davon, wie sie implementiert ist. Die Verwendung anstelle von intist ein logischer Fehler.

  • Was ist der Grund, trotz der Warnung NULLanstelle von 0 den Rückgabewert zu verwenden main()?

Ignoranz. Es gibt keinen guten Grund dafür.

  • Ist die Implementierung definiert, ob dies angemessen ist oder nicht, und wenn ja, warum sollte eine Implementierung einen Zeigerwert zurückerhalten wollen?

Nein, das ist niemals angebracht . Es liegt an der Implementierung, ob der Compiler dies zulässt . Ein konformer C ++ - Compiler kann dies ohne Vorwarnung zulassen.

Konrad Rudolph
quelle
1
Mein üblicher Schlag: Es ist nicht implementierungsdefiniert, ob der Compiler dies zulässt; es ist implementierungsspezifisch . In der Norm bedeutet "implementierungsdefiniert", dass die Implementierung dokumentieren muss, was sie tut.
Pete Becker
@PeteBecker Ich habe beim Schreiben eine Pause eingelegt, bin aber trotzdem weitergegangen (weil "implementierungsspezifisch" und ähnliche Sätze einfach unnatürlich klingen). Aber du hast recht, ich werde es ändern.
Konrad Rudolph
Mir scheint, dass der einzige Grund, warum "implementierungsdefiniert" natürlich klingt, darin besteht, dass die Leute daran gewöhnt sind, dass es missbraucht wird. <g>
Pete Becker
8

Wenn ich diesen Code mit gcc kompiliere, erhalte ich die Warnung:

warning: return makes integer from pointer without a cast

Dies liegt daran, dass Sie mit laxen Compileroptionen kompilieren. Wenn Sie strenge C-Standardeinstellungen verwenden -std=c11 -pedantic-errors, wird bei Implementierungen, bei denen die NULLErweiterung auf die Nullzeigerkonstante erweitert wird, der erwartete Compilerfehler angezeigt (void*)0. Siehe "Zeiger von Ganzzahl / Ganzzahl von Zeiger ohne Umwandlung" .

Bei Implementierungen, bei denen NULLerweitert wird, 0ist der Code streng genommen standardkonform, aber sehr schlecht, nicht portabel und am schlimmsten: völliger Unsinn.

Und kompiliere es mit g ++, ich bekomme eine gleichwertige Warnung:

warning: converting to non-pointer type int from NULL [-Wconversion-null]

Unter C ++ 11 und höher NULLsollte nicht verwendet werden - stattdessen verwenden nullptr. Die Rückgabe von main () ist trotzdem falsch. NULLErweitert sich 0in C ++ immer so streng, dass es funktioniert, aber es ist ein sehr schlechter Stil und das Schlimmste von allem: völliger Unsinn.

Ist es nur ein schlechter Codierungsstil?

Nicht nur schlecht, sondern unsinniger Codierungsstil ohne Begründung. Der Programmierer, der es geschrieben hat, war inkompetent.

Lundin
quelle
2

Ist es nur ein schlechter Codierungsstil?

Schlechter. Der richtige Weg, um anzuzeigen, dass das Programm einwandfrei beendet wurde, ist

#include <stdlib.h>

int main (void)
{
    return EXIT_SUCCESS;
}
Emacs macht mich verrückt
quelle
1
Das ist reine Pedanterie. Gemäß dem C-Standard bedeutet ein 0-Argument für exit()(oder ein 0-Rückgabewert von main) dasselbe wie EXIT_SUCCESS.
Mosvy
Und da c99 können Sie einfach weglassen das returnaus main. Also, eine "korrektere" Version Ihres Programms ist int main(void){};-)
Mosvy
1

In? Einige / viele / alle? C ++ - Implementierungen NULLsind ein Makro, auf das erweitert wurde 0.

Dies ergibt bei erweiterter Wirkung return 0. Welches ist ein gültiger Rückgabewert.

Ist es nur ein schlechter Codierungsstil?

Ja.

Robert Andrzejuk
quelle