main()からNULLを返す理由


10

CやC ++プログラムでのNULL戻り値として使用するコーダーが時々見られます。main()たとえば、次のようなものです。

#include <stdio.h>

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

    return NULL;
} 

このコードをgccでコンパイルすると、次の警告が表示されます。

警告:キャストなしでポインタから整数を返す[-Wint-conversion]

これは、マクロNULLが展開され(void*) 0、mainの戻り値がtypeであるため、妥当intです。

私が短いC ++プログラムを作るとき:

#include <iostream>
using namespace std;

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

    return NULL;
}

そして、それをg ++でコンパイルすると、同等の警告が表示されます。

警告:NULLから非ポインター型 'int'に変換しています[-Wconversion-null]

しかし、なぜ警告をスローするときのNULL戻り値として使用するのmain()でしょうか。それは単に悪いコーディングスタイルですか?


  • 警告にもかかわらず、の戻り値としてのNULL代わりに使用する理由は何ですか?0main()
  • これが適切であるかどうかは実装定義であり、適切である場合、なぜ実装はポインタ値を取り戻したいのでしょうか?

4
あなたは彼らに直接尋ねるべきです。
ジャンチョパンザ

5
「なぜmain()の戻り値としてNULLを使用するのか」-私たちは使用しません。そのコードの作成者が行います。理由を正当化する彼らの試みを聞きたいと思います。
WhozCraig

1
@モスクワの@Vladはい、でもそれが本当に0だったかどうか確認する必要がEXIT_FAILUREありました。
Waelmio

2
@RobertSsupportsMonicaCellioそれが本当にあなたが得た応答だったとしたら、それはちょっと悲しいことです。第一に、それは意味をなさない(それがどこよりもどこにでもあったらもっと意味があるだろう)。第二に、売り切れです。コードを記述している場合は、それが正しいかどうかについて優れたコンパスを用意することをお勧めします。誰かがそれをしているように見えるので、それだけで行くのではありません。あなたはその針が正しい方向を指しているように見えます(したがって、なぜあなたが尋ねているのでしょう)。そのコードを書いた人ではなく、理由としてその答えをあなたに与えました。
WhozCraig

2
cでは、NULLポインタを0(へのキャストなしでvoid *)として定義することは完全に有効です。この場合、欠陥は気付かれず、警告は生成されません。それでも、NULLを使用する必要はありません。
Ctx

回答:


14

それは合理的です

はい。

マクロNULLは、(void*) 0

いいえ。C++では、マクロを[support.types.nullptr]に展開しNULL ないで(void*) 0ください。Cでのみ可能です。

どちらの方法でも、実装方法に関係なくnullポインター定数NULLを参照することになっているため、このようなコードの記述は誤解を招く可能性があります。の代わりに使用するintと、論理エラーになります。

  • 警告NULLmain()もかかわらず0の代わりに戻り値として使用する理由は何ですか?

無知。これを行う正当な理由はありません。

  • これが適切であるかどうかは実装定義であり、適切である場合、なぜ実装はポインタ値を取り戻したいのでしょうか?

いいえ、それは決して適切ではありません。コンパイラが許可するかどうかは、実装次第です。準拠しているC ++コンパイラは、警告なしにそれを許可する場合があります。


1
私のいつものどきどき:コンパイラがそれを許可するかどうかは実装定義されていません。それはimplemenation固有。標準では、「実装定義」は、実装が何をするかを文書化する必要があることを意味します。
ピートベッカー

@PeteBecker作成時に一時停止しましたが、とにかく先に進みました(「実装固有」や類似のフレーズが不自然に聞こえるため)。しかし、あなたは正しい、私はそれを変更します。
コンラートルドルフ

「実装定義」が自然に聞こえる唯一の理由は、人々がそれが誤用されているのを見ていることに慣れているからだと私には思われます。<g>
ピートベッカー

8

このコードをgccでコンパイルすると、次の警告が表示されます。

warning: return makes integer from pointer without a cast

これは、laxコンパイラー・オプションを使用してコンパイルするためです。厳密なC標準設定-std=c11 -pedantic-errorsを使用NULLすると、nullポインター定数に展開される実装で、予期されるコンパイラエラーが発生します(void*)0「キャストなしの整数からのポインター/ポインターからの整数」の問題を参照してください。

がにNULL展開される実装では0、コードは厳密に言えば標準に準拠していますが、スタイルが非常に悪く、移植性がなく、最悪の場合、完全なナンセンスです。

そして、それをg ++でコンパイルすると、同等の警告が表示されます。

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

C ++ 11以降でNULLは使用しないでくださいnullptr。代わりにを使用してください。それをmain()から返すことは、正しくありません。NULL常に0C ++に展開されるため、厳密に言えば機能しますが、スタイルが非常に悪く、最悪の場合、完全にナンセンスです。

それは単に悪いコーディングスタイルですか?

悪いだけでなく、根拠のないナンセンスなコーディングスタイル。それを書いたプログラマーは無能でした。


2

それは単に悪いコーディングスタイルですか?

さらに悪い。プログラムが正常に終了したことを示す正しい方法は

#include <stdlib.h>

int main (void)
{
    return EXIT_SUCCESS;
}

1
それは純粋な歩みです。C標準によれば、引数0 exit()(またはメインからの戻り値0)はと同じ意味EXIT_SUCCESSです。
モスビー

また、c99以降は単にreturnfromを省略できますmain。したがって、プログラムのより「正しい」バージョンはint main(void){};-)です
mosvy

1

いくつか/多く/すべて?C ++実装NULLは、に拡張されたマクロ0です。

実際に展開するとこれができますreturn 0。これは有効な戻り値です。

それは単に悪いコーディングスタイルですか?

はい。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.