2

gcc コンパイラからの警告メッセージについて質問があります。警告メッセージは、scanf の引数が、ユーザー入力を運ぶ変数へのポインターではない場合に発生します。

#include <stdio.h>

int main(int argc, const char *argv[]) {
    float number;
    scanf("%f", number); /* the value of 'number' is passed, instead of the adress to it */
    return 0;
}

gcc は、プログラムのコンパイル時に次の警告メッセージを表示します。

scanf-problem.c: In function 'main':
scanf-problem.c:5:5: warning: format '%f' expects argument of type 'float *', but argument 2 has type 'double' [-Wformat=]
     scanf("%f", number);
     ^

予想通り、gcc は scanf の 2 番目の引数に型 'float *' (float へのポインター) を持たせたいと考えています。私を悩ませているのは、gcc が 2 番目の引数の型が「double」であると信じているのに、実際には型が「float」であるということです。

なぜ gcc は scanf の 2 番目の引数が double であると信じているのに、実際には float なのですか?

答えを得るためにこのトピックについていくつかの調査を行いましたが、見つけたすべての答えは、警告を取り除く方法に関するものです (「番号」ではなく「&番号」と書きます)。

4

5 に答える 5

4

なぜ gcc は scanf の 2 番目の引数が double であると信じているのに、実際には float なのですか?

C標準で指定されているようにfloat昇格されるためdouble

6.5.2.2 関数呼び出し

[#6] ... float 型の引数は double に昇格されます。これらは、デフォルト引数プロモーションと呼ばれます。

[#7] ... 関数プロトタイプ宣言子の省略記号表記により、最後に宣言されたパラメーターの後で引数の型変換が停止します。デフォルトの引数昇格は、末尾の引数に対して実行されます。

于 2013-09-27T12:20:34.933 に答える
3

scanfあなたは間違ったことを(コメントで述べたように)に渡していることをすでに知っていfloatますdouble.

于 2013-09-27T11:06:33.020 に答える
3

あなたのコンパイラは正しいです。渡された引数scanfは実際にはdouble:...引数リストの一部に対して、一連のデフォルト変換が実行されます。特に、すべてのfloat引数が昇格されdouble、これがscanf見られるものです。

于 2013-09-27T12:14:28.943 に答える
1

[編集] プロトタイプを投稿する以外scanf()に、答えが @chill に反響するようになりました。
「模倣はお世辞の最も誠実な形です。」


プロトタイプを確認してくださいscanf()

int scanf(const char * restrict format, ...);

つまり...、任意の数の任意のタイプの引数が許可されます。歴史的な理由から、より小さいのすべての FP 引数は、そのような関数に渡されたときにdouble昇格されます。doubleそのため、コンパイラはそれをdouble.

char、 にshortも昇進しintます。

C11 6.5.2.2 6

" ... 整数昇格は各引数で実行され、型が float の引数は double に昇格されます。これらはデフォルト引数昇格と呼ばれます。 ... "

于 2013-09-27T14:29:00.733 に答える