2

プロトタイプが指定するよりも小さい配列として引数が定義されている場合に警告できるツール (できれば Linux) はありますか?

例えば:

void somefunc(float arg[10]);  /* normally this would be defined in a header */

void my_func(void)
{
    float arg[2];
    somefunc(arg);  /* <-- this could be a warning */
}

これは無効なコードではないことは認識していますが、警告を発することができれば、いくつかのよくある間違いを解決できる可能性があります (最近これらのバグの 1 つに遭遇しました)。

関数が同じファイルにあり、配列の境界外に値を設定すると、いくつかのツール (clang static checker など) が警告しますが、arg がプロトタイプ単独よりも小さい場合に何かが警告するかどうか疑問に思っていました。

私はcppcheck、clang、smatch、splint、gccの-Wextraを使用しました...しかし、これについて文句を言う人はいません。

4

4 に答える 4

8

プロトタイプの値はコンパイラにとって意味がなく、無視されます! 上記で宣言された関数は次と同等です

void somefunc(float* arg);

void somefunc(float arg[]);

C++ を使用する場合、参照を使用してコンパイル時のサイズ制限に対処できます。本当に 10 の配列が必要な場合はfloat、参照によって渡すことができます。これにより、サイズが正しいことが強制されます。

void somefunc(float (&arg)[10]);

ただし、これにより、より大きな配列が渡されなくなります。より大きな配列を渡したい場合は、テンプレート転送関数で遊ぶことができます。

void somefunc_intern(float* arg);
template <int Size>
typename std::enable_if<(10 <= Size)>::type
somefunc(float (&arg)[Size]) {
    somefunc_intern(arg);
}

もちろん、これは警告を生成しませんが、小さすぎる配列が渡された場合はエラーを生成します。

于 2012-10-04T06:19:59.747 に答える
3

C言語では、パラメーターfloat arg[10]配列の境界は単に文体的なものです。これは、コンパイラーではなく、プログラマーへのヒントです。C の型チェックは弱いため、任意の種類の float ポインターまたは配列を関数に渡すことができます。パラメーターを渡す前に関数のドキュメントを読まないプログラマーはトラブルを求めていると主張する人もいるかもしれません。しかし、もちろん、偶発的なバグが発生する可能性は常にあります。

優れたコンパイラはこれに対して警告します。警告を表示しない悪いコンパイラを使用している場合は、実際に外部の静的解析ツールの使用を検討する必要があります。これらのツールは、疑わしい型変換に対して常にうるさいことで有名です。Lintには Linux バージョンがあり、私は使用していませんが、大きくて複雑なものに代わる手頃な価格の代替手段として知られています。

理論的には、コンパイラがより多くの警告を生成するコードを作成できますが、プログラムが難読化されます。私はそれをお勧めしません、それは次のようになります:

void somefunc(float (*arr_ptr)[10])
{
  float* arg = *arr_ptr;
  ...
}

int main()
{
  float ten[10];
  float two[2];

  somefunc(ten);  // warning
  somefunc(&ten); // warning
  somefunc(two);  // warning
  somefunc(&two); // warning

  float (*ten_ptr)[10] = &ten;
  float (*two_ptr)[2] = &two;

  somefunc(ten_ptr) // ok
  somefunc(two_ptr) // warning

}
于 2012-10-04T07:00:46.420 に答える
1

この質問をして以来、cppcheckは私の提案に応えてこの機能を追加しました(みんなありがとう!)、

コミット: https ://github.com/danmar/cppcheck/commit/7f6a10599bee61de0c7ee90054808de00b3ae92d

問題: http ://sourceforge.net/apps/trac/cppcheck/ticket/4262

これを書いている時点ではまだリリースされていませんが、次のリリースになると思います。

于 2012-12-22T08:41:59.217 に答える
-1

std::array<N>代わりに または C 配列を使用すると、まったく普通の C++ コンパイラでコンパイル エラーが発生します。

それで、それをするだけですか?

于 2012-10-04T06:32:16.333 に答える