18

私はこのような機能を持っています:

#include <setjmp.h>
jmp_buf buf;
void func2(int g);
extern int some_global;
void func(int x)
{
    if (setjmp(buf))
        return;
    if (some_global)
        x += 5;
    func2(x);
}

GCC (gcc (Debian 4.4.5-8) 4.4.5) は警告を出します:

test.c: 関数 'func' 内:
test.c:5: 警告: 引数 'x' は 'longjmp' または 'vfork' によって破壊される可能性があります [-Wclobbered]

どうして????xつまり、返品後は使用できない可能性があるため、が壊れているかどうかは明らかに気にしませんsetjmpコンパイラでさえ、ある種の特別な知識を持っていることを考えると、非常に明白なことを認識しているはずですsetjmp

私の主な関心は、継承したコード ベースのバグを見つけることなので、「代わりにこのコーディング スタイルを使用してください」というアドバイスは求めていません。ただし、ここには多くの奇妙なひねりがあります。たとえば、xがパラメーターではなくローカル変数である場合、GCC は文句を言いません。また、GCC はこの行がなくても文句を言いませんif (some_global)。良い。何かが GCC のフロー解析を台無しにしているか、GCC が私が知らない何かを知っているのかもしれません。

そう、

  • 未使用のパラメーターをにキャストできるのと同じ方法で、この関数のこの警告を抑制する簡単な方法はあります(void)か?

  • それとも、プロジェクト全体で警告を抑制するだけですか?

  • または、何か不足していますか?

更新:警告を生成しないわずかに異なるバージョンを共有させてください:

#include <setjmp.h>
jmp_buf buf;
void func2(int g);
extern int some_global;
void func(int y)
{
    int x = y;
    if (setjmp(buf))
        return;
    if (some_global)
        x += 5;
    func2(x);
}
4

2 に答える 2

6

からman longjmp:

自動変数の値は、次の基準をすべて満たす場合、longjmp() の呼び出し後に未指定になります。

   ·  they are local to the function that made the corresponding setjmp(3)
      call;

   ·  their  values  are  changed  between  the  calls  to  setjmp(3)  and
      longjmp(); and

   ·  they are not declared as volatile.

たまたま、x最初の例の変数は次の基準を満たしています。

  • 関数のパラメーターローカル自動変数と同様であるため、関数に対してローカルです。
  • setjmpその値は、 ifsome_globalが true の直後に変更される可能性があります。
  • 揮発性ではありません。

そのため、その値は指定されていない (上書きされている) 可能性があります。

2番目のバージョンが警告を出さない理由について...わかりません。

于 2011-10-11T12:38:38.380 に答える