1

C プログラムを長い間デバッグしたところ、関数呼び出しを行うときに引数を見逃していたことがわかりました。このような愚かな間違いは本当にイライラしますが、コンパイラはこれを検出できるはずだと思います. (C はデフォルト引数さえサポートしていません。C++ でも、デフォルト引数は明示的に宣言する必要があります。)

更新: プロトタイプも間違っていることがわかりました...

では、一致しない関数呼び出しの引数番号を警告するための GCC フラグはありますか? 私はいつも持っ-Wall-pedanticいます。このような明白なエラーが検出されないことは非常に驚くべきことです。(実際には、GCC が報告しない理由があると思いますが、現時点では考えられません。)

恥ずかしいコード例:

    static void dfs();

    int main(int argc, const char *argv[]) {
         dfs(1);
    }

    static void
    dfs(int remain, int last) {
        // dfs
    }

私が行ったもう 1 つの発見は、プロトタイプに引数が含まれている場合、コンパイラが報告することです。しかし、プロトタイプにはたまたま引数が含まれていなかったため、コンパイラはスリップしました。

4

2 に答える 2

4

関数呼び出し引数の数が一致しないことは、すべてのコンパイラが特別な設定なしで提供する必須の診断です。規格で義務付けられています。

C99Standard 6.5.2.2 関数呼び出し:
制約

呼び出される関数を表す式がプロトタイプを含む型を持つ場合、引数の数はパラメーターの数と一致する必要があります。各引数は、その値が対応するパラメータの型の修飾されていないバージョンを持つオブジェクトに割り当てられるような型を持つものとします。


 static void dfs();

を返す関数であり、dfs指定されていない数の引数を取ることができることをコンパイラに伝えます。さらに、2 つの引数を取り、同じものを呼び出す関数の定義を提供します。ご覧のとおり、契約の破棄はありません。問題は、関数の宣言が正しくないことです。引数を取らない関数を宣言したい場合は、次を使用する必要があります。staticvoid

 static void dfs(void);

これを行うと、コンパイラは診断を提供します

于 2013-03-31T05:01:21.367 に答える
0

使用できるさまざまなオプションがあります。

  • -Wstrict-prototypes
  • -Wmissing-prototypes
  • -Wold-style-definition
  • -Wold-style-declaration

これらは、使用していない場合でも機能します-std=c99。私はオフィスで旧式のコードに悩まされて-Wstrict-prototypesおり、「処理」されていないコードをクリーンアップするときにこれら (を除く) を使用しています。例外は、コード ベース内の関数へのポインターには必要な引数リストがないことがほとんどであるためです。個人的なコード、または私が担当しているコードの場合、これは問題ではありません。

于 2013-03-31T05:35:17.953 に答える