14

次のコードが機能します。

int main()
{
   void foo(int);
   foo(3);
   return 0;
}
void foo(a) int a;
{
   printf("In foo\n");
}

しかし、これはしません:

int main()
{
   void foo(float);
   foo(3.24);
   return 0;
}
void foo(a) float a;
{
   printf("In foo\n");
}

なぜこれが起こるのですか?

4

1 に答える 1

22

実際、興味深い質問です。

これは、C 言語の進化と、古いフレーバーとの下位互換性を確保する方法に関係しています。

どちらの場合も、 の K&R 時代の定義がありますがfoo()、以前は C99 宣言 (プロトタイプを使用) があります。

ただし、最初のケースでは、int実際のデフォルトのパラメーターはパラメーターであるため、関数呼び出しは互換性があります。

ただし、2 番目のケースでは、K&R の定義は K&R 時代の標準的な引数昇格規則を取り入れており、パラメーターの型は reallydoubleです。

しかし、呼び出しサイトで最新のプロトタイプを使用したため、float. そのため、呼び出しサイトのコードは実際の をプッシュした可能性がありますがfloat、これはいずれにせよ とは異なる型ですdouble

へのすべての参照foo()が K&R スタイルである場合、ほとんどの場合、警告が表示されると思います。これは当時のコンパイラが行っていたことであり、コンパイラはレガシー コードをコンパイルするためにそのように動作する必要があります。少なくともプロシージャ呼び出しインターフェイスでは、float がすべて double に昇格されるため、タイプ セーフな呼び出しでさえあります。(内部関数コードとは限りません。)

于 2011-01-29T18:10:30.643 に答える