ベクトルを返す(パブリック)関数を備えたクラスがあります(しかし、それは無関係のようです)。
std::vector<int> test() {
return std::vector<int>(1,0);
}
void 関数と同じように呼び出すことができるのはなぜですか?
test();
コンパイルエラー、または少なくとも警告(ウォール、ペダンティック)を取得せずに?
ベクトルを返す(パブリック)関数を備えたクラスがあります(しかし、それは無関係のようです)。
std::vector<int> test() {
return std::vector<int>(1,0);
}
void 関数と同じように呼び出すことができるのはなぜですか?
test();
コンパイルエラー、または少なくとも警告(ウォール、ペダンティック)を取得せずに?
戻り値は破棄できます。一般的には良いスタイルではありませんが、いつでもできます。
これが、リターンタイプをオーバーロードできない理由の1つです。したがって、別の関数void test()
を定義すると、あいまいさのために呼び出しができなくなります。
戻り値を(意図せずに)破棄するような場合にコンパイラーに警告させたい場合は、フラグを渡します-Wunused-result
(GCCの場合)。[他のコンパイラのフラグはわかりません]
一般に、ほとんどすべての戻り値は意味があります。そのため、このマクロを使用して、意図せずに値を破棄した場合を検出する場合があります。特に、戻り値が後でチェックする必要があるエラーコードのようなものである場合はそうです。
特定の関数の警告を有効にする場合は、署名の最後に属性を配置できます(GCCの場合も、MSVCの場合はこの質問を参照してください)。
std::vector<int> __attribute__((warn_unused_result)) test() {
return std::vector<int>(1,0);
}
したがって、関数を呼び出しても戻り値を使用しない場合は、警告が表示されます。警告によってコンパイルが失敗することはありません。この-Werror
ため、コンパイラフラグに追加する必要があります。
コンパイラは単に戻り値を破棄するからです。これについて警告するオプションがコンパイラにあるかもしれませんが、デフォルトでは有効になっていません。
(戻り値がないため) void 関数の戻り値を変数に代入しようとするのはエラーですが、実際の戻り値を破棄するのはエラーではありません。これは、関数呼び出しにはまだ副作用がある可能性があり、おそらく戻り値は情報にすぎないためです (たとえば、常に成功を期待している場合のステータス コード)。このようなシナリオのため、言語設計者は、C++ で戻り値を取得せずに非 void 関数を呼び出しても問題ないと判断しました。