Czasami widzę kodery, które wykorzystują NULL
jako wartość zwracaną main()
w programach C i C ++, na przykład coś takiego:
#include <stdio.h>
int main()
{
printf("HelloWorld!");
return NULL;
}
Kiedy kompiluję ten `kod z gcc, pojawia się ostrzeżenie:
ostrzeżenie: return tworzy liczbę całkowitą ze wskaźnika bez rzutowania [-Wint-konwersji]
co jest uzasadnione, ponieważ makro NULL
należy rozszerzyć do, (void*) 0
a wartość zwracana dla main powinna być typu int
.
Kiedy tworzę krótki program w C ++:
#include <iostream>
using namespace std;
int main()
{
cout << "HelloWorld!";
return NULL;
}
I skompiluj to z g ++, dostaję równoważne ostrzeżenie:
ostrzeżenie: konwersja na typ nieinterpretacyjny „int” z NULL [-Wconversion-null]
Ale dlaczego używają NULL
jako wartości zwracanej, main()
gdy wyświetla ostrzeżenie? Czy to po prostu zły styl kodowania?
- Jaki jest powód, aby użyć
NULL
zamiast0
wartości zwracanejmain()
pomimo ostrzeżenia? - Czy jest to zdefiniowane jako implementacja, czy jest to właściwe, czy nie, a jeśli tak, to dlaczego implementacja miałaby chcieć odzyskać wartość wskaźnika?
EXIT_FAILURE
ma 8, i wydaje się, że użycie 1 nie jest dobre na niepowodzenie, ponieważ czasami jest używane jako sukces w niektórych programach.NULL
wskaźnika jako0
(bez rzutowania navoid *
). W takim przypadku wada pozostaje niezauważona i nie generuje ostrzeżenia. Nadal nie jest to, do czego NULL powinien być używany.Odpowiedzi:
Tak.
Nie. W C ++ makro
NULL
nie może rozwijać się do(void*) 0
[support.types.nullptr]. Może to zrobić tylko w C.Tak czy inaczej pisanie takiego kodu jest mylące, ponieważ
NULL
powinno odnosić się do stałej wskaźnika zerowego , niezależnie od tego, jak jest zaimplementowane. Używanie go zamiastint
logicznego błędu jest logiczne.Ignorancja. Nie ma dobrego powodu, aby to zrobić.
Nie, to nigdy nie jest właściwe . To od implementacji zależy, czy kompilator na to pozwoli . Zgodny kompilator C ++ może na to pozwolić bez ostrzeżenia.
źródło
Jest tak, ponieważ kompilujesz z opcjami kompilatora Lax. Użyj surowych ustawień standardowych C,
-std=c11 -pedantic-errors
a otrzymasz oczekiwany błąd kompilatora w implementacjach, w którychNULL
rozwija się do stałej wskaźnika zerowego(void*)0
. Zobacz problemy „Wskaźnik od liczby całkowitej / liczba całkowita od wskaźnika bez rzutowania” .W implementacjach, w których
NULL
rozwija się0
, kod jest ściśle zgodny ze standardami, ale bardzo zły styl, nieprzenośny i co najgorsze: kompletny nonsens.W C ++ 11 i późniejszych
NULL
nie należy go używać - zamiast tego należy użyćnullptr
. Zwrócenie go z main () jest niezależnie od tego niepoprawne.NULL
zawsze rozwija się0
w C ++, więc ściśle mówiąc, to zadziała, ale jest to bardzo zły styl, a co najgorsze: kompletna bzdura.Nie tylko zły, ale nonsensowny styl kodowania bez żadnego uzasadnienia. Programista, który to napisał, był niekompetentny.
źródło
Gorzej. Prawidłowym sposobem wskazania, że program został poprawnie ukończony, jest
źródło
exit()
(lub wartość zwracana 0 z main) oznacza to samo coEXIT_SUCCESS
.return
zmain
. Tak więc bardziej „poprawną” wersją twojego programu jestint main(void){}
;-)W? Niektórych / wielu / wszystkich? Implementacje C ++
NULL
to makro rozwinięte do0
.To po rozszerzeniu daje efekt
return 0
. Która jest prawidłową wartością zwracaną.Tak.
źródło