web-dev-qa-db-ja.com

function()とfunction(void)の違いは何ですか?

次のようにパラメータとして何も受け取らない関数を書くのは良い習慣だと聞いています:

int func(void);

しかし、それを表現する正しい方法は次のようであると聞きます:

int func();

CとC++の両方でのこれら2つの関数宣言の違いは何ですか?

32
Grizzly

CとC++はこの点で異なります。

C 2011オンライン標準

6.7.6.3関数宣言子(プロトタイプを含む)
...
10 voidタイプの名前のないパラメーターがリスト内の唯一の項目であるという特殊なケースでは、関数にパラメーターがないことを指定しています。
...
14識別子リストは、関数のパラメーターの識別子のみを宣言します。関数の定義の一部である関数宣言子の空のリストは、関数にパラメーターがないことを指定します。関数の定義の一部ではない関数宣言子の空のリストは、パラメーターの数またはタイプに関する情報が提供されないことを指定します。145)

つまり、関数declarationの空のパラメーターリストは、関数がunspecifiedの数のパラメーターを取る一方で、空のパラメーターがあることを示します。関数のリストdefinitionは、関数がnoパラメータを取ることを示します。

T foo( void ); // declaration, foo takes no parameters
T bar();       // declaration, bar takes an *unspecified* number of parameters

T foo( void ) { ... } // definition, foo takes no parameters
T bar() { ... }       // definition, bar takes no parameters

Cに関する限り、関数宣言または定義では空の識別子リストを使用しないでください。関数がパラメーターを取ることを意図していない場合は、パラメーターリストでvoidを使用して指定します。

オンラインC++標準

8.3.5関数[dcl.fct]
...
4parameter-declaration-clauseは、関数が呼び出されたときに指定できる引数とその処理を決定します。 [注:parameter-declaration-clauseは、関数呼び出しで指定された引数を変換するために使用されます。 5.2.2を参照してください。 —end note]parameter-declaration-clauseが空の場合、関数は引数を取りません。非依存型voidの単一の名前のないパラメーターで構成されるパラメーターリストは、空のパラメーターリストと同等です。この特別な場合を除いて、パラメーターはタイプcv voidを持たないものとします。 parameter-declaration-clauseが省略記号または関数パラメーターパック(14.5.3)で終了する場合、引数の数は、次のパラメーターの数以上でなければなりません。デフォルト引数がなく、関数パラメーターパックではありません。構文的に正しく、「...」がabstract-declaratorの一部ではない場合、「、...」は「...」と同義です。 [例:宣言
    int printf(const char*, ...);
さまざまな数と型の引数で呼び出すことができる関数を宣言します。
    printf("hello world");
    printf("a=%d b=%d", a, b);
ただし、最初の引数はconst char*に変換できる型である必要があります_ —end example] [注:標準ヘッダー<cstdarg>には、省略記号を使用して渡された引数にアクセスするためのメカニズムが含まれています(5.2.2および18.10を参照)。 —end note]

C++の場合、宣言または定義のいずれかで空のパラメーターリストは、関数が引数を取らないことを示し、voidのパラメーターリストを使用することと同等です。

20
John Bode

Cでは、空のパラメーターリスト()を持つ関数は、引数としてanythingを取ることができます。文字通り何でも。これは通常、 可変数の引数 をとることができる関数を実装するために使用されますが、最近では、これらの関数に対してより明示的な省略構文(...)を使用することが推奨されています。

Cでは、パラメーターリスト(void)のある関数は、引数として明示的にnothingを取ります。これは、何かを渡そうとすると、コンパイラが実際にミスをしたと通知できることを意味します。

C++では、これらの関数宣言は同等です。空白のパラメーターリストは、voidと同じように「パラメーターなし」を意味します。

36
Ixrec