void func() {assert(0);}
int main() {void func();}
上記のコードはfunc()を呼び出さないか、少なくともアサーションには達しません。私は本当に知る必要はありませんが、私はちょうど興味があります、ここで何が起こっているのですか?関数呼び出しの先頭にC++のvoidがあります。例えば。
void func() {assert(0);}
int main() {void func();}
上記のコードはfunc()を呼び出さないか、少なくともアサーションには達しません。私は本当に知る必要はありませんが、私はちょうど興味があります、ここで何が起こっているのですか?関数呼び出しの先頭にC++のvoidがあります。例えば。
何も返さず引数をとらないfunc
という名前の関数のプロトタイプを宣言しています。それは、関数呼び出しと関数プロトタイプの微妙な違いの1つです。 main
より上の行、void func() {assert(0);}
は、これがプロトタイプかコールかに影響しないことに注意してください。あなたはそれを削除することができ、コードは同じことを行うでしょう - つまり、何もしません。
これは、関数プロトタイプを再宣言できることも示しています。
int main() {
void blah();
void blah();
void blah();
void blah();
}
そして、コードは以前と同じように何もしません。
void
を省略すると、関数が呼び出されます。また
、パラメータを取る関数の場合には、この旨の通知:あなたはこのようにそれの前にvoid
を追加した場合
int main() { func(4); }
はプロトタイプに変身しません:
int main() { void func(4); }
それは構文エラーが発生します。
関数が不要な場合でも宣言することができます。それがあなたがやったことです、機能を再宣言しました。他の人が指摘したように
、ライン
void func();
main
の内部は、関数プロトタイプではなく関数func
へのコールとして扱われます。 CやC++では、関数プロトタイプを関数内で宣言することはできますが、実際にはあまり行われません。
これが法的であるという事実は、プログラマーのためにあらゆる種類の頭痛を引き起こします。たとえば、あなたが
(void) func();
ように、コードを書き直した場合、その後、これはその戻り値の型が明示的に示すために、void
にキャストされfunc
への呼び出しとしてコンパイルします「私はこの戻り値を気にしないでください。」つまり、この括弧のセットは宣言を文に変更します。
、この問題は、以下のこのコードは関数プロトタイプではなく、デフォルトのコンストラクタを呼び出し、変数の宣言であるという事実によって悪化することができます。
Object myObject(137);
を作成しますが
Object myObject();
そのオブジェクトをコンストラクタに渡します。
Object myObject;
creaコンストラクタを呼び出さずにオブジェクトに問い合わせます。
コンストラクタを呼び出している間にオブジェクトを宣言しようとしたときに発生する「最も厄介な構文解析」と呼ばれる言語の酷い場合があります。たとえば、このコードでは、法律上のC++ですが、それは関数宣言ではなく、変数の宣言です:問題は、この関数の宣言ではなく、一時的な2を受け入れ、オブジェクトの生成として解析することができることである
set<int> mySet(istream_iterator<int>(cin), istream_iterator<int>());
パラメータとしてistream_iterator<int>
を含む。この問題を解決するには、C++であなたは
set<int> mySet(istream_iterator<int>(cin), (istream_iterator<int>()));
、上記のように、余分な括弧を強制的に宣言であることに、関数のプロトタイプであることから、文を明確に記述する必要があると思います。
希望すると便利です。
ローカル関数void func()
をmain()
の中に宣言しています。 void
ステートメントは、それが宣言であり、関数呼び出しではないことをコンパイラーに示します。したがって、void
を削除すると、関数が呼び出されます。