1. ホーム
  2. c++

[解決済み] なぜこのC++スニペットはコンパイルできるのか(非void関数が値を返さない) [duplicate]

2022-07-04 03:26:21

質問

今朝、ある図書館でこれを見つけました。

static tvec4 Min(const tvec4& a, const tvec4& b, tvec4& out)
{
    tvec3::Min(a,b,out);
    out.w = min(a.w,b.w);
}

このメソッドは何も返さないので、コンパイラーエラーになると思いますし、戻り値の型が void .

の2つしか思い浮かびません。

  • このメソッドが呼び出される唯一の場所で、戻り値が使用または保存されていません。(このメソッドは本来 void - が tvec4 の戻り値はコピーアンドペーストのエラーです)

  • で構成されるデフォルトの tvec4 が作成されるのは、C++の他のすべてのものと少し違っているようです。

私はこれに対処する C++ の仕様の部分を見つけられませんでした。リファレンス(ハ)があるとありがたいです。

更新

いくつかの を実行すると、VS2012でエラーが発生します。具体的な内容は絞りきれていませんが、それでも興味深いです。

解決方法は?

これは 未定義の動作 から C++11 標準草案 セクション 6.6.3 returnステートメント パラグラフ 2 というのがありますが

[...] 関数の最後を流すことは、値を持たない戻り値と同じです。これは、値を返す関数では未定義の動作となります。[...]

これは、すべての場合において診断が困難であるため、コンパイラは通常エラーや警告を提供する義務はないことを意味します。このことは 未定義の動作 の定義からもわかります。 1.3.24 という記述があります。

[...]許容される未定義の動作は、予測できない結果を伴う状況の完全な無視から、翻訳中またはプログラム実行中に環境に特有の文書化された方法で動作すること(診断メッセージの発行の有無を問わず)、翻訳または実行を終了すること(診断メッセージの発行あり)までです[...] 。

この場合、両方を得ることができますが gccclang を使用してワンリングを生成します。 -Wall フラグを使用してワンリングを生成すると、このような警告が表示されます。

警告: 制御は非ボイド関数の終わりに達しました [-Wreturn-type] 。

この警告をエラーにするために -Werror=return-type フラグを使用します。また、私は -Wextra -Wconversion -pedantic を使うのも好きです。

でComicSansMSが言及しているように Visual Studio このコードでは C4716 という、デフォルトではエラーとなるメッセージが表示されます。

error C4716: 'Min' : 値を返さなければなりません。

で、すべてのコードパスが値を返すわけではない場合、次のように生成されます。 C4715 という警告が表示されます。