次のようにパラメータとして何も受け取らない関数を書くのは良い習慣だと聞いています:
int func(void);
しかし、それを表現する正しい方法は次のようであると聞きます:
int func();
CとC++の両方でのこれら2つの関数宣言の違いは何ですか?
CとC++はこの点で異なります。
6.7.6.3関数宣言子(プロトタイプを含む)
...
10void
タイプの名前のないパラメーターがリスト内の唯一の項目であるという特殊なケースでは、関数にパラメーターがないことを指定しています。
...
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
を使用して指定します。
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
のパラメーターリストを使用することと同等です。
Cでは、空のパラメーターリスト()
を持つ関数は、引数としてanythingを取ることができます。文字通り何でも。これは通常、 可変数の引数 をとることができる関数を実装するために使用されますが、最近では、これらの関数に対してより明示的な省略構文(...)
を使用することが推奨されています。
Cでは、パラメーターリスト(void)
のある関数は、引数として明示的にnothingを取ります。これは、何かを渡そうとすると、コンパイラが実際にミスをしたと通知できることを意味します。
C++では、これらの関数宣言は同等です。空白のパラメーターリストは、void
と同じように「パラメーターなし」を意味します。