回答:
Davidの答えは、この動機をかなりカバーしています。この関数が返すことを知っているが、明示的に無視していることを他の「開発者」に明示的に示します。
これは、必要なエラーコードが常に処理されるようにする方法です。
完全な静的キャスト表記の使用はここではやり過ぎのように感じるので、C ++の場合、これはおそらくCスタイルのキャストを使用することを好む唯一の場所だと思います。最後に、コーディング標準をレビューまたは記述している場合は、オーバーロードされた演算子への呼び出し(関数呼び出し表記を使用しない)もこれから免除されることを明示的に示すこともお勧めします。
class A {};
A operator+(A const &, A const &);
int main () {
A a;
a + a; // Not a problem
(void)operator+(a,a); // Using function call notation - so add the cast.
仕事では、それを使用して関数に戻り値があることを認めますが、開発者はそれを無視しても安全であると断言しました。質問にC ++のタグを付けたので、static_castを使用する必要があります。
static_cast<void>(fn());
コンパイラーが返す限り、戻り値をvoidにキャストしても意味がありません。
これを行う本当の理由は、lintと呼ばれるCコードで使用されるツールにさかのぼります。
コードを分析して、起こりうる問題を探し、警告と提案を出します。関数がチェックされなかった値を返したlint
場合、これが偶発的である場合に警告します。lint
この警告を黙らせるには、に呼び出しをキャストします(void)
。
キャストvoid
は、未使用の変数や未保存の戻り値または式に対するコンパイラの警告を抑制するために使用されます。
規格(2003)は§5.2.9/ 4で述べています、
任意の式を明示的に「cv void」型に変換できます。式の値は破棄されます。
だからあなたは書くことができます:
//suppressing unused variable warnings
static_cast<void>(unusedVar);
static_cast<const void>(unusedVar);
static_cast<volatile void>(unusedVar);
//suppressing return value warnings
static_cast<void>(fn());
static_cast<const void>(fn());
static_cast<volatile void>(fn());
//suppressing unsaved expressions
static_cast<void>(a + b * 10);
static_cast<const void>( x &&y || z);
static_cast<volatile void>( m | n + fn());
すべてのフォームが有効です。私は通常次のように短くします:
//suppressing expressions
(void)(unusedVar);
(void)(fn());
(void)(x &&y || z);
それも大丈夫です。
c ++ 17以降[[maybe_unused]]
、void
キャストの代わりに使用できる属性があります。
nodiscard
興味深いかもしれないC ++ 17も追加しました:stackoverflow.com/a/61675726/895245また、私はあなたが[[maybe_unused]]
思われる呼び出しに直接適用することはできません、呼び出しの戻りを受け入れるダミー変数にのみ適用できますか?それが正しければ、少し不安定です。
プログラムの機能上、voidへのキャストは意味がありません。また、Davidの回答で示唆されているように、コードを読んでいる人に何かを知らせるためにそれを使用しないでください。自分の意図について何かを伝えたい場合は、コメントを使用することをお勧めします。このようなキャストを追加すると、奇妙に見えるだけで、考えられる理由についての質問が発生します。ただ私の意見...
For the functionality of you program casting to void is meaningless
自己文書化とコンパイル時の警告の数については、実際にはそうではありません。コードがそれ自体を説明するとき、you should not use it to signal something to the person that is reading the code [...] it is better to use a comment.
最高のコメントはコメントなしです。そして、繰り返しになりますが、その過程で有効な警告コンパイラを満足させます。
C ++ 17 [[nodiscard]]
C ++ 17は、「戻り値無視ビジネス」を属性で標準化しました。
したがって、準拠した実装が常にnodiscard
指定された場合にのみ警告し、それ以外の場合は警告しないことを願っています。
例:
main.cpp
[[nodiscard]] int f() {
return 1;
}
int main() {
f();
}
コンパイル:
g++ -std=c++17 -ggdb3 -O0 -Wall -Wextra -pedantic -o main.out main.cpp
結果:
main.cpp: In function ‘int main()’:
main.cpp:6:6: warning: ignoring return value of ‘int f()’, declared with attribute nodiscard [-Wunused-result]
6 | f();
| ~^~
main.cpp:1:19: note: declared here
1 | [[nodiscard]] int f() {
|
以下はすべて警告を回避します。
(void)f();
[[maybe_unused]] int i = f();
私は通話でmaybe_unused
直接使用することができませんでしたf()
:
[[maybe_unused]] f();
与える:
main.cpp: In function ‘int main()’:
main.cpp:6:5: warning: attributes at the beginning of statement are ignored [-Wattributes]
6 | [[maybe_unused]] f();
| ^~~~~~~~~~~~~~~~
(void)
鋳造作業は必須ではありませんが、標準で「奨励」されています。どのように私は意図的に[[nodiscard]]の戻り値を破棄することができますか?
また、警告メッセージからわかるように、警告の「解決策」の1つは次のように追加すること-Wno-unused-result
です。
g++ -std=c++17 -ggdb3 -O0 -Wall -Wextra -pedantic -Wno-unused-result -o main.out main.cpp
もちろん、このようにグローバルに警告を無視することはお勧めしません。
C ++ 20では、https://en.cppreference.com/w/cpp/language/attributes/nodiscardで説明nodiscard
され[[nodiscard("reason")]]
ているように、理由をに追加することもできます。
GCC warn_unused_result
属性
の標準化の前[[nodiscard]]
、およびCが最終的に属性の標準化を決定する前に、GCCはとまったく同じ機能を実装しましたwarn_unused_result
。
int f() __attribute__ ((warn_unused_result));
int f() {
return 1;
}
int main() {
f();
}
それは与える:
main.cpp: In function ‘int main()’:
main.cpp:8:6: warning: ignoring return value of ‘int f()’, declared with attribute warn_unused_result [-Wunused-result]
8 | f();
| ~^~
ANSI Cにはこのための標準がないため、ANSI CはどのC標準ライブラリ関数が属性を持っているかどうかを指定せず、したがって実装はでマークする必要があるかどうかについて独自の決定を行っていますwarn_unuesd_result
。そのため、一般に、(void)
キャストを使用して標準ライブラリ関数の呼び出しの戻りを無視し、実装での警告を完全に回避する必要があります。
GCC 9.2.1、Ubuntu 19.10でテスト済み。