14

私は(すぐに)いくつかのコードを書いていて、誤って引数を反転させていましたscanf()

char i[] = "ABC1\t";
scanf(i, "%s");

でコンパイルするとgcc -Werror -Wall -Wextra、これについて少し文句はありません。明らかに、このコードは機能しませんが、引数を反転したことを gcc が通知しなかったのはなぜですか? iフォーマット文字列ではないこと、または 2 番目の引数が格納可能な型ではないことを検出できませんか?

EDIT
すべての洞察に感謝します。答えを見つけたようです。-Wformatこれを「キャッチ可能」にするフラグにひねりがありました(参照用に以下に投稿)

4

3 に答える 3

18

ハ!見つけた。-Wformat=2フラグを付けて gcc を押すと、それがキャッチされました。

他の人の参考のために情報を投稿する:

これが私が見つけたフラグのリストです

-Wformat Check calls to printf and scanf, etc., to make sure that the arguments supplied have types appropriate to the format string specified...

私はそれが含まれていると思って-Wall-Wformatましたが、私が見つけたものの本当に重要な部分は次のとおりです。

-Wformat is included in -Wall. For more control over some aspects of format checking, the options -Wformat-y2k, -Wno-format-extra-args, -Wno-format-zero-length, -Wformat-nonliteral, -Wformat-security, and -Wformat=2 are available, but are not included in -Wall.

于 2012-10-25T12:47:15.787 に答える
8

すべきではないと思います。

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

iは通常 に変換されconst char*、残りのパラメータはすべて「省略記号」であり、コンパイル時にチェックできません。

于 2012-10-25T12:37:49.727 に答える
3

scanf のマニュアル エントリ (man scanf) は、プロトタイプを提供します。

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

char[] は単なる特別な型の char * であるため、最初の引数は満たされます。2 次引数は実行時に評価されるため (思い出すと)、ここではコンパイラーによっても考慮されません。コンパイラの見通しからすると、これはプロトタイプが与えられた関数への適切な呼び出しです。

また、コンパイラは、無効な場所に書き込もうとしているかどうかを確認しません。C の素晴らしい (またはひどい) 点は、たとえそれが悪い考えであっても、多かれ少なかれやりたいことを実行できることです。

于 2012-10-25T12:40:39.563 に答える