27

__attribute__ ((warn_unused_result))関数によって返されるエラーコードを無視しないように開発者を促す手段として非常に役立つことがわかりましたが、MSVC、およびgccやICCなどのgcc互換コンパイラで動作するためにこれが必要です。Microsoft Visual Studio C / C ++コンパイラには同等のメカニズムがありますか?(これまでのところ、運が悪かったので、MSDNをくぐり抜けてみました。)

4

5 に答える 5

16

です_Check_return_。同様のアノテーションの例についてはここを、関数の動作についてはここを参照してください。MSVC2012以降でサポートされています。

例:

_Check_return_
int my_return_must_be_checked() {
    return 42;
}
于 2014-03-31T07:12:23.437 に答える
14

MSVC2012以降の更新

_Check_return_SAL静的コード分析を使用する場合にMSVCがVisualStudio2012の時点で注釈をサポートするようになったことを指摘してくれた、@Albertに感謝します。他の人に役立つ可能性のあるクロスプラットフォームマクロを含めることができるように、この回答を追加しています。

#if defined(__GNUC__) && (__GNUC__ >= 4)
#define CHECK_RESULT __attribute__ ((warn_unused_result))
#elif defined(_MSC_VER) && (_MSC_VER >= 1700)
#define CHECK_RESULT _Check_return_
#else
#define CHECK_RESULT
#endif

gcc et alとは異なり、(a)MSVCは関数の宣言定義の両方に注釈を付ける必要があり、(b)注釈は宣言/定義の先頭にある必要があることに注意してください(gccはどちらかを許可します)。したがって、通常、使用法は次のようにする必要があります。


// foo.h

CHECK_RETURN int my_function(void); // declaration


// foo.c

CHECK_RETURN int my_function(void)  // definition
{
    return 42;
}


コマンドラインからコンパイルする場合は/analyze(または)スイッチ が必要であり、VisualStudioIDEを使用する場合は同等のスイッチが必要になることにも注意してください。-analyzeこれはまた、ビルドをいくらか遅くする傾向があります。

于 2014-03-31T10:33:45.203 に答える
5

VisualStudioの一部のエディションには、以前はPREFast(現在は単に「C / C ++のコード分析」と呼ばれています)と呼ばれていた静的分析ツールがパッケージ化されています。PREFastは、注釈を使用してコードをマークアップします。それらの注釈の1つであるMustCheckは、探していることを実行します。

于 2010-11-19T15:34:32.400 に答える
3

私の知る限り、MSコンパイラには同等のプラグマまたは属性がありません。適切な警告レベルでオプティマイザをオンにした場合に取得できる「未使用」タイプの警告は、変数に対するものだけです。

于 2010-11-19T15:21:02.943 に答える
2

他の人が言及しているSALアノテーションは、MSVCの正しい答えだと思いますが、MSVC、GCC、およびGCC互換のコンパイラよりも移植性に関心がある人もいると思います。したがって…</ p>

まず、GCCはwarn_unused_result3.4以降のみをサポートします。が定義されているかどうかを確認するだけでなく、 / の値を確認することもできますが、現時点では、3.4より前のバージョンのGCCを使用している人を想像するのは困難です。__GNUC____GNUC_MINOR____GNUC__

いくつかのコンパイラはGCCスタイルの関数属性をサポートしており、次のように定義する場合としない場合があります__GNUC__

  • Clang(でチェック__has_attribute(warn_unused_result))、およびそれに基づくコンパイラ(emscripten、xlc 13+、armclangなど)。ただし、AFAIKでは常に少なくともGCC 4.2になりすますため、明示的なチェックはおそらく必要ありません。
  • Intelは常に定義しているわけではありません__GNUC__-no-gccフラグを参照)。彼らがいつそれをサポートし始めたかはわかりませんが(彼らのドキュメントはひどく不足しています)、16.0+が安全であることは知っています。
  • TI8.0+はそれをサポートします
  • TI 7.3+は、-gccが渡されたときにそれをサポートします。 __TI_GNU_ATTRIBUTE_SUPPORT__あるときに定義されます。
  • Oracle Developer Studio 12.6+は、CではなくC++モードでサポートします。
  • PGIはC++モードでそれをサポートします。AFAICTは文書化されていないため、いつ追加されたかはわかりませんが(#1650-D)、17.10以降には間違いなく存在します。Cモードでは黙って無視され、いつか実装されることを願っています。

さらに、C++17は属性を追加し[[nodiscard]]ます。[[nodiscard]]C++17モード でサポートするバージョンのGCC/clangの場合[[gnu::nodiscard]]、C ++ 11以降のモードでも使用できますが、マクロの背後に隠している場合は、代わりにそうする理由がわかりません。を使用するだけ__attribute__((__warn_unused_result__))です。

まとめると、Hedleyには次のようなHEDLEY_WARN_UNUSED_RESULTマクロがあります。

#if defined(__cplusplus) && (__cplusplus >= 201703L)
#  define HEDLEY_WARN_UNUSED_RESULT [[nodiscard]]
#elif \
  HEDLEY_GNUC_HAS_ATTRIBUTE(warn_unused_result,3,4,0) || \
  HEDLEY_INTEL_VERSION_CHECK(16,0,0) || \
  HEDLEY_TI_VERSION_CHECK(8,0,0) || \
  (HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
  (HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
  HEDLEY_PGI_VERSION_CHECK(17,10,0)
#  define HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
#elif defined(_Check_return_) /* SAL */
#  define HEDLEY_WARN_UNUSED_RESULT _Check_return_
#else
#  define HEDLEY_WARN_UNUSED_RESULT
#endif

Hedley(パブリックドメイン/ CC0)を使用したくない場合は、内部のHedleyマクロを取り除き、ロジックをそれほど問題なくコピーできるはずです。そうすることを選択した場合は、おそらくリポジトリ内のバージョンに基づいてポートを作成する必要があります。これは、この回答を新しい情報で最新の状態に保つことを覚えている可能性がはるかに低いためです。

于 2018-03-24T18:33:45.753 に答える