Perché restituire NULL da main ()?


10

A volte vedo programmatori che usano NULLcome valore di ritorno main()nei programmi C e C ++, ad esempio qualcosa del genere:

#include <stdio.h>

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

    return NULL;
} 

Quando compilo questo codice con gcc ricevo l'avvertimento di:

avvertenza: return rende intero dal puntatore senza cast [-Wint-conversion]

che è ragionevole perché la macro NULLdeve essere espansa (void*) 0e il valore di ritorno di main deve essere di tipo int.

Quando realizzo un breve programma C ++ di:

#include <iostream>
using namespace std;

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

    return NULL;
}

E compilarlo con g ++, ricevo un avviso equivalente:

avvertenza: conversione in tipo non puntatore 'int' da NULL [-Wconversion-null]

Ma perché usano NULLcome valore di ritorno main()quando emette un avviso? È solo un cattivo stile di codifica?


  • Qual è il motivo da utilizzare NULLanziché 0come valore di ritorno main()nonostante l'avviso?
  • È definito dall'implementazione se questo è appropriato o meno e, in caso affermativo, perché qualsiasi implementazione dovrebbe voler recuperare un valore puntatore?

4
Dovresti chiedere loro direttamente.
juanchopanza,

5
"perché usano NULL come valore di ritorno di main ()" - noi no. L'autore di quel codice lo fa. Sarei interessato a sentire il loro tentativo di giustificare il perché.
WhozCraig

1
@Vlad da Mosca sì, ma ho dovuto verificare se era davvero 0. ^^ - EXIT_FAILUREè 8, e sembra che usare 1 non sia un errore, dato che a volte è usato come successo in alcuni programmi.
Waelmio,

2
@RobertSsupportsMonicaCellio se questa è stata davvero la risposta che hai ricevuto, è un po 'triste. In primo luogo, non ha senso (avrebbe più senso se fosse ovunque piuttosto che ovunque ). In secondo luogo, è esaurito. Se stai scrivendo un codice, è meglio avere una buona bussola sul fatto che sia corretto; non basta, perché è così che sembra fatto da ... qualcuno. Sembra che tu abbia quell'ago puntato nella giusta direzione (quindi perché lo stai chiedendo); non tanto la persona che ha scritto quel codice, poi ti ha dato quella risposta come il motivo.
WhozCraig

2
In c, è perfettamente valido definire il NULLpuntatore come 0(senza cast a void *). In questo caso, il difetto passa inosservato e non genera un avviso. Non è ancora quello per cui NULL dovrebbe essere usato.
Ctx

Risposte:


14

che è ragionevole

Sì.

perché la macro NULLdeve essere espansa a(void*) 0

No. In C ++ la macro NULL non deve espandersi in (void*) 0[support.types.nullptr]. Può farlo solo in C.

In entrambi i casi, scrivere codice come questo è fuorviante poiché NULLsi suppone che faccia riferimento alla costante del puntatore null , indipendentemente da come è implementato. Usarlo al posto di un intè un errore logico.

  • Qual è la ragione per usare NULLinvece di 0 come valore di ritorno main()nonostante l'avviso?

Ignoranza. Non ci sono buoni motivi per farlo.

  • È definito dall'implementazione se questo è appropriato o meno e, in caso affermativo, perché qualsiasi implementazione dovrebbe voler recuperare un valore puntatore?

No, non è mai appropriato . Spetta all'implementazione se il compilatore lo consente . Un compilatore C ++ conforme potrebbe consentirlo senza preavviso.


1
Il mio solito colpo: non è definito da implementaiton se il compilatore lo consente; è specifico dell'attuazione . Nella norma "definito dall'implementazione" significa che l'implementazione deve documentare ciò che fa.
Pete Becker,

@PeteBecker Mi sono messo in pausa durante la scrittura, ma sono comunque andato avanti (perché "specifiche dell'implementazione" e frasi simili sembrano semplicemente innaturali). Ma hai ragione, lo cambierò.
Konrad Rudolph,

Mi sembra che l'unica ragione per cui "definita dall'implementazione" sembra naturale è che le persone sono abituate a vederlo usato in modo improprio. <g>
Pete Becker,

8

Quando compilo questo codice con gcc ricevo l'avvertimento di:

warning: return makes integer from pointer without a cast

Questo perché si compila con opzioni di compilatore lassiste. Usa rigide impostazioni standard C -std=c11 -pedantic-errorse otterrai l'errore del compilatore previsto, sulle implementazioni in cui si NULLespande alla costante puntatore null (void*)0. Vedere i problemi "Puntatore da intero / intero da puntatore senza cast" .

Sulle implementazioni in cui si NULLespande 0, il codice è rigorosamente conforme allo standard, ma stile pessimo, non portatile e, peggio ancora: totale assurdità.

E compilarlo con g ++, ricevo un avviso equivalente:

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

Su C ++ 11 e versioni successive, NULLnon dovrebbe essere usato, invece utilizzare nullptr. Restituirlo da main () non è corretto a prescindere. NULLsi espande sempre 0in C ++, quindi in senso stretto funzionerà, ma è uno stile pessimo e, peggio ancora: assurdità completa.

È solo un cattivo stile di codifica?

Stile di codifica non solo cattivo, ma senza senso, senza alcuna logica. Il programmatore che l'ha scritto era incompetente.


2

È solo un cattivo stile di codifica?

Peggio. Il modo corretto per indicare che il programma è stato completato correttamente è

#include <stdlib.h>

int main (void)
{
    return EXIT_SUCCESS;
}

1
È pura pedanteria. Secondo lo standard C, un argomento 0 a exit()(o un valore di ritorno 0 da main) significa lo stesso di EXIT_SUCCESS.
mosvy

E dal c99 puoi semplicemente omettere il returnda main. Quindi, una versione più "corretta" del tuo programma è int main(void){};-)
mosvy

1

In? Alcuni / molti / tutti? Le implementazioni C ++ NULLsono una macro espansa a 0.

Questo quando espanso in effetti dà return 0. Quale è un valore di ritorno valido.

È solo un cattivo stile di codifica?

Sì.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.