質問

いすべての私のコード(C++)を無視の戻り値です。どうしたらよい-gccは静的コード解析ツールなのでしょうか?

悪いコードの例:

int f(int z) {
    return z + (z*2) + z/3 + z*z + 23;
}


int main()
{
  int i = 7;
  f(i); ///// <<----- here I disregard the return value

  return 1;
}

ご注意:

  • この組合せだったとしても動作が可能であり、その利用の異なるファイル
  • 無料 静チェックツール
役に立ちましたか?

解決

あなたはGCCのwarn_unused_result属性を望んます:

#define WARN_UNUSED __attribute__((warn_unused_result))

int WARN_UNUSED f(int z) {
    return z + (z*2) + z/3 + z*z + 23;
}

int main()
{
  int i = 7;
  f(i); ///// <<----- here i disregard the return value
  return 1;
}

このコードをコンパイルしようとすると、生成します:

$ gcc test.c
test.c: In function `main':
test.c:16: warning: ignoring return value of `f', declared with
attribute warn_unused_result

あなたはでの使用でこれを見ることができますLinuxカーネルに、彼らは同じことを__must_checkマクロを持っています。あなたが動作するように、このためのGCC 3.4以降が必要のように見えます。その後、カーネルヘッダファイルで使用されているマクロがあります:

unsigned long __must_check copy_to_user(void __user *to,
                                        const void *from, unsigned long n);

他のヒント

私の知る限り承知しているとして、この警告を与えるために何GCCのオプションはありません。あなたが特定の機能に興味がある場合は、あなたは属性とそれらにタグを付けることができます:

int fn() __attribute__((warn_unused_result));

FNの戻り値が()を使用しなかった場合に警告を与えるであろう。警告:私は自分自身を、この機能を使用したことがありません。

あなたは、実行時にそれを行うには、この便利なテンプレートを使用することができます。

の代わりに、エラーコードを返すのは、(例えば、HRESULT)は、あなたはそれが価値が読まれずにスコープから外れた場合にアサートRETURN_CODE を返します。これは、静的解析ツールではありませんが、それはどれもあまり役に立たません。

class return_value
{
public:
  explicit return_value(T value)
    :value(value), checked(false)
  {
  }

  return_value(const return_value& other)
    :value(other.value), checked(other.checked)
  {
    other.checked = true;
  }

  return_value& operator=(const return_value& other)
  {
    if( this != &other ) 
    {
      assert(checked);
      value = other.value;
      checked = other.checked;
      other.checked = true;
    }
  }

  ~return_value(const return_value& other)
  {
    assert(checked);
  }

  T get_value()const {
    checked = true;
    return value;
  }

private:
  mutable bool checked;
  T value;
};

C ++ 17この質問の変化への答えのために我々は今、を持っているので、 [[nodiscard]] の属性。 [dcl.attr.nodiscard] のでカバー>

  

属性トークンnodiscardは、関数宣言、またはクラスまたは列挙の宣言に宣言-IDに適用されてもよいです。これは、各属性リストで、最高1回表示されなければならず、何の属性引数句が存在しないものとします。

  

struct [[nodiscard]] error_info { /* ... */ };
error_info enable_missile_safety_mode();
void launch_missiles();
void test_missiles() {
  enable_missile_safety_mode(); // warning encouraged
  launch_missiles();
}
error_info &foo();
void f() { foo(); }             // warning not encouraged: not a nodiscard call, because neither
                                // the (reference) return type nor the function is declared nodiscard
     

- 終了例]

だから、(それはを生きる参照)あなたの例を修正します:

[[nodiscard]] int f(int z) {
    return z + (z*2) + z/3 + z*z + 23;
}


int main()
{
  int i = 7;
  f(i); // now we obtain a diagnostic

  return 1;
}

私たちは今、例えばgccと打ち鳴らすの両方で診断を得る。

warning: ignoring return value of function declared with 'nodiscard' attribute [-Wunused-result]
  f(i); // now we obtain a diagnostic
  ^ ~

任意の静的解析コード(例えば PC-Lintのの)あなたにそれを伝えることができるはずです。 PC-Lintのために、私はこれが事実であることを知っています。

静的アナライザは、あなたのための作業を行いますが、あなたのコードベースは、些細なが圧倒されるように準備し、より多くの場合; - )

静的アナライザは、あなたの最善の策はここになります。私たちは、あなたが同様に使用できることをを利用できる無料ツール。

あなたは間に合わせと-ソリューションを必要としますが、便利なLinuxスタイルのシェルを持っている場合は、あなたのような何かを試すことができます:

grep -rn "function_name" * | grep -v "="

これは、指定された関数を参照するが、「=」が含まれていないすべての行を見つけます。あなたは偽陽性(および潜在的にいくつかの偽陰性)の多くを得ることができますが、あなたは静的アナライザを持っていない場合には、開始するには、まともな場所です。

クラシック「のlint」プログラムは、無視された値を返し機能について非常に口八丁にするために使用しました。トラブルがあったこれらの警告の多くは不要だった - (それはあなたがそれを無視したかった綿毛のビットを拾った)リント出力に過度のノイズにつながります。 GCCは、それのための標準的な警告を持っていない理由は、おそらくです。

他の問題 - フリップサイドは - 「あなたは結果を無視している知っているとき、どのように警告を抑制しますが、本当に気にしない」です。そのための古典的なシナリオがあります:

if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
    signal(SIGHUP, sighandler);

あなたはsignal()からの最初の結果を気に。あなたは(あなたがちょうどそれにそれを設定しているため)第二はSIG_IGNになることを知っています。警告から離れて取得するには、私は時々にいくつかのバリアントを使用します:

if ((old = signal(SIGHUP, SIG_IGN)) != SIG_IGN)
    old = signal(SIGHUP, sighandler);

これは、両方の時間をoldに割り当てます。あなたは、 'アサート(旧== SIG_IGN)' でそれに従うことができます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top