web-dev-qa-db-ja.com

g ++関数の戻り値を無視すると警告を受け取る方法

lintは、次のような警告を生成します。

foo.c XXX Warning 534: Ignoring return value of function bar()

糸くずから 手動

534関数の戻り値を無視する

'Symbol'(Locationと比較)値を返す関数は、たとえば、ステートメント自体またはコンマ演算子の左側のように、副作用のためだけに呼び出されます。試してください:(void)function();関数を呼び出し、その戻り値を無視します。 §5.5「フラグオプション」のfvr、fvo、およびfdrフラグも参照してください。

コンパイル中にこの警告があれば、それを受け取りたいです。これを実現するためのgcc/g ++のオプションはありますか? -Wallをオンにしましたが、明らかにこれを検出しませんでした。

26
Arun

回答とコメントを寄せてくれた WhirlWindpaxdiablo に感謝します。これが、完全な(?)答えにピースをまとめる私の試みです。

-Wunused-result関連するgccオプションです。そしてデフォルトでオンになっていますgcc警告オプションページ からの引用:

-Wno-unused-result

属性warn_unused_result変数属性 を参照)でマークされた関数の呼び出し元がその戻り値を使用しない場合でも警告しません。デフォルトは-Wunused-resultです。

したがって、解決策は、関数にwarn_unused_result属性を適用することです。

これが完全な例です。ファイルunused_result.cの内容

int foo() { return 3; }

int bar() __attribute__((warn_unused_result));
int bar() { return 5; }

int main()
{
    foo();
    bar();    /* line 9 */
    return 0;
}

および対応するコンパイル結果:

$gcc unused_result.c 
unused_result.c: In function ‘main’:
unused_result.c:9: warning: ignoring return value of ‘bar’, declared with attribute warn_unused_result

はデフォルトであるため、-Wunused-resultを持つ必要はないことに再度注意してください。意図を伝えるために、それについて明示的に言及したくなるかもしれません。それは高潔な意図ですが、状況を分析した後、私の選択はそれに反対するでしょう。なぜなら、コンパイルオプションに-Wunused-resultがあると、all関数がない限り、真実ではない誤ったセキュリティ/満足感が生成される可能性があるためです。コードベースはwarn_unused_resultで修飾されます。

27
Arun

C++ 17以降、 [[nodiscard]]属性

例:

[[nodiscard]] int bar() {
  return 42;
}
18
Jyaif

-Wunused-resultあなたのためにこれを行う必要があります。これは警告の1つではありません-壁がオンになります:

http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html

関数にはwarn_unused_result属性を適用する必要があります(paxdiabloに感謝)。

6
WhirlWind

__attribute__((warn_unused_result))の使用に関する答えは正しいです。ただし、GCCはこの機能があまり得意ではありません。注意:非PODタイプについては警告しません。つまり、たとえば、デストラクタを含むクラス(またはデストラクタを含むインスタンス変数を含むクラス)を返す場合、結果を無視することについての警告は表示されません。

関連するバグ: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66177

失敗する例:

struct Error {
~Error();
};

__attribute__((warn_unused_result)) Error test();

int main()
{
    test();
    return 0;
}

したがって、非常に単純ではない戻り値の型については、これに依存しないでください。

4
Jonah

私はこのような問題を解決しました:

_#define ignore_result(x) if (x) {}
_

次に、_(void)foo()_の代わりにignore_result(foo())を使用します

次に、コードは_-Wall_で正常にコンパイルされます。

0
Sasha Pachev