5

この質問は、C++11 または C でパラメーターがないことを意味する「f(void)」の派生物ですか?

何人かがその質問に答え、C では関数プロトタイプの意味は

void func ()

つまり、 func は何も返さない (void) 関数であり、そのパラメーターは現時点では不明です。

さらに彼らは、この宣言を行ってから、次のようないくつかの引数を使用して関数を呼び出すことができると意見を述べています。

func (1, 2, 3);

それで、私はこれを行い、これが機能することを確認するためにテストを行いました。

これが func.c です。main()

#include <stdio.h>

extern void func ();

int main (int ac, char ** av)
{
  func (1, 2, 3);

  return 0;
}

そして、ここに関数を含む func1.c がありますfunc()

#include <stdio.h>

void func (int a, int b, int c)
{
  printf ( "%d, %d, %d\n", a, b, c );
}

そして、ここに私の質問があります

質問1:

このプログラムを実行すると、予想どおり、出力 1、2、3 が得られます。これはコードを安全に記述する方法ですか。つまり、ABI は、func()inの呼び出しがmain()3 つのパラメーターを適切な場所 (レジスター、スタックなど) に配置func()して、それらを見つけることを確実に保証すると仮定できますか?

質問2:

上記の 1 に対する答えが、安全に行うことができるというものである場合func()、C 以外の言語で実装されている場合、答えは変わりますか?

4

2 に答える 2

12

C について、または C++ について質問していますか?

C にはもともと関数プロトタイプがありませんでした。あなたは書くでしょう:

extern void func();

そしてそれを定義します:

void func( a, b, c )
    int a;
    int b;
    int c;
{
    //  ...
}

C++ は関数プロトタイプを追加し、上記を違法にしました。そして宣言:

extern void func();

パラメータを持たない関数を宣言しました。引数を指定して呼び出すと、引数を指定して定義する場合と同様にエラーになります。

次に、C は C++ から関数プロトタイプを追加しました。しかし、既存のコードを壊さないようにするために、それらを必要とせず、処理しました

extern void func();

以前と同様: 不明な数と型のパラメータを取る関数。したがって、次のようにも追加されました。

extern void func(void);

関数がパラメータを取らないことを示す特別な方法として。C++ は、C との互換性のために、この特殊なケースを追加しました。

一般的なルールは、C++ では次のように書くことです。

extern void func();

フォームを使用するのvoidは、両方の言語と互換性がなければならないヘッダーだけです。もちろん、C では、このフォームは意図したとおりに動作しないため、. を追加する必要がありますvoid。(今のところ。私の理解では、C は古い形式を非推奨にしているため、将来的には、この点で C++ とまったく同じように動作する可能性があります。)

編集:

調べたところ. C11 標準から、§6.11.6:

括弧が空の関数宣言子 (プロトタイプ形式のパラメーター型宣言子ではない) の使用は廃止予定の機能です。

Cではやらないでください。

于 2013-08-22T11:30:41.980 に答える
1

Q1. 引数が正しい型であれば、うまくいくかもしれません (おそらくうまくいくでしょう)。しかしfunc(1.2, "blah");、それが何をするか試してみてください - クラッシュしないという意味で「うまくいく」かもしれません - 確かにコンパイルされます。

Q2. Q1の回答をご覧ください。まったく安全ではありません。

于 2013-08-22T11:33:08.587 に答える