C ++またはCではfoo(void)とfoo()の間に違いはありますか?


253

次の2つの関数の定義を検討してください。

void foo() { }

void foo(void) { }

これら2つの間に違いはありますか?そうでない場合、なぜvoidそこに議論があるのですか?美的理由は?


Cの場合、Q / Aはこちら
Antti Haapala、2018年

回答:


317

ではC

  • void foo()foo不特定のタイプの不特定の数の引数を取る 関数」を意味します
  • void foo(void)foo引数を取らない関数」を意味します

ではC ++

  • void foo()foo引数を取らない関数」を意味します
  • void foo(void)foo引数を取らない関数」を意味します

foo(void)したがって、を記述することで、両方の言語で同じ解釈を実現し、ヘッダーを多言語にします(通常、ヘッダーをさらにクロスランゲージにするために、ヘッダーにさらにいくつかの処理を行う必要があります。つまり、extern "C"コンパイルしている場合は、 C ++)。


10
しかし、C ++がを必要とした場合void、「最も厄介な解析」の問題を回避できたはずです。
エイドリアンマッカーシー

5
確かに、しかしC ++には他にも多くのくだらない解析があり、それらのいずれかをkvetchingすることには真の意味がありません。
DrPizza

16
最近の質問で、@ James Kanzeが興味深い一口を投稿しました。失われないようにここに再投稿します。Cの最初のバージョンでは、関数が取る可能性のあるパラメーターの数を指定できなかったため、関数void foo()を宣言する唯一の構文でした。署名が導入されたとき、C委員会はパラメータなしを古い構文から明確にする必要があり、void foo(void)構文を導入しました。C ++は互換性のためにそれを採用しました。
Matthieu M.

3
void foo()代わりにvoid foo(void)を使用すると機能に違いが生じるC C90以降の例を教えてください。つまり、私は何年もボイドのないバージョンを使用しており、何の問題も見ていません。
chacham15

6
@ chacham15はvoid foo() { if ( rand() ) foo(5); } コンパイルして実行します(非常に幸運でない限り、未定義の動作を引き起こします)。一方void foo(void)、同じ本体を使用すると、コンパイルエラーが発生します。
MM

39

あなたの質問はC ++に関するものだと思いますが、Cに関してはK&Rの72〜73ページに答えがあります。

さらに、関数宣言に引数が含まれていない場合、次のようになります。

double atof();

これも、atofの引数について何も想定されていないことを意味すると解釈されます。すべてのパラメーター検査がオフになります。空の引数リストのこの特別な意味は、古いCプログラムが新しいコンパイラでコンパイルできるようにすることを目的としています。しかし、新しいプログラムで使用するのは悪い考えです。関数が引数を取る場合は、それらを宣言します。引数を取らない場合は、voidを使用します。


しかし、問題は定義に関するものです。その場合、関連するCルールは次のとおりです。関数の定義の一部である関数宣言子の空のリストは、関数にパラメーターがないことを指定します。
jinawee 2018

9

C ++ 11 N3337標準ドラフト

違いはありません。

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf

付録C「互換性」C.1.7条項8:宣言者は次のように述べています。

8.3.5変更:C ++では、空のパラメーターリストで宣言された関数は引数を取りません。Cでは、空のパラメーターリストは、関数の引数の数と型が不明であることを意味します。

例:

int f();
// means int f(void) in C ++
// int f( unknown ) in C

理論的根拠:これは、誤った関数呼び出し(つまり、引数の数またはタイプが間違っている関数呼び出し)を回避するためです。

元の機能への影響:明確に定義された機能のセマンティクスへの変更。この機能は、Cでは「廃止」としてマークされていました。

8.5.3関数は言う:

4. parameter-declaration-clauseは、関数が呼び出されたときに、指定できる引数とその処理を決定します。[...] parameter-declaration-clauseが空の場合、関数は引数を取りません。パラメーターリスト(ボイド)は、空のパラメーターリストと同等です。

C99

C ++ 11で言及されているようにint f()、引数については何も指定せず、廃止予定です。

コードまたはUBが機能する可能性があります。

私はC99標準を詳細に解釈しました:https : //stackoverflow.com/a/36292431/895245


2

Cでは、空の関数参照でvoidを使用して、コンパイラーにプロトタイプがあり、そのプロトタイプに「引数がない」ようにします。C ++では、プロトタイプを省略できないため、プロトタイプがあることをコンパイラに通知する必要はありません。


1
「プロトタイプ」とは、引数リストの宣言と戻り値のタイプを意味します。「プロトタイプ」が最初にあなたが何を意味していたのか私を混乱させたので、私はこれを言います。
Zan Lynx、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.