3

Sun Studio 12.1 が警告を出力します。

Warning: The last statement should return a value.

そのような機能のために頻繁に:

int f()
{
  /* some code that may return */

  // if we end up here, something is broken
  throw std::runtime_error("Error ...");
}

関数の最後に戻り値が必要ないことは明らかです。次のようなものを挿入するのをためらっています

// Silence a compiler warning
return 42;

とにかくデッドコードであるため、そのような関数の最後に。より複雑な戻り値の型の場合、「適切な」偽の値を構築するのは実際には難しい場合があります。

そのような警告を黙らせるための推奨される方法は何ですか?

4

5 に答える 5

4

通常のパスが関数の最後に発生するように関数内のコードを再編成できますか (願わくばもっと論理的にも) ?

編集: 関数の再編成が本当に意味をなさない場合は、いつでもreturn 0;コメント付きのダミーを置くことができます。よりグローバルに警告するよりも、そのように警告を押しつぶす方がよいでしょう。

警告を完全に消したい場合は、使用できます#pragma error_messages (off, wnoretvalue)が、ほとんどの場合、警告は本当に役立つので、オフにすることは絶対にお勧めしません。プラグマのバージョンを使用してon、関数の後に警告を再度有効にすることができますが、関数がインライン展開された場合、コンパイラは引き続き警告を発します。関数を独自のソース ファイルに配置し、他の翻訳単位に影響を与えないため、警告を比較的安全にシャットアウトするプラグマを使用する場合。

もう 1 つの非常に風変わりな可能性は、g++ に切り替えることです。SPARC g++ 用にコンパイルしていない限り、実際には Sun スタジオよりも優れたコードを生成する可能性があります。

于 2011-04-12T15:21:12.957 に答える
3

に最適な場所だと思いますabort()。あなたによると、あなたは決してそこで終わるべきではないので、次のようなものです:

UNREACHABLE("message")

これは次のように展開されます:

#ifdef NDEBUG
  #define UNREACHABLE(Message_) abort();
#else
  #define UNREACHABLE(Message_) assert(0 && Message_);
#endif

適切に見える

于 2011-04-12T15:24:17.153 に答える
2

例外が体系的に呼び出されることがわかっているので、単純に 0 を返さないのはなぜですか?

于 2011-04-12T15:20:42.317 に答える
1

おそらく、コンテンツをdo { } while (false);構造 にカプセル化します。

int my_function()
{
  int result = DEFAULT_VALUE;
  do
  {
     result = /*...*/
     // Whatever
     if (error)
     {
       throw std::runtime_error("Error ...");
     }
   } while (false);
   return result;
}

アイデアは、通常の操作で結果値を設定してから、実行を最後までフローさせるか、 a を使用してステートメントbreakにジャンプすることです。return

于 2011-04-12T16:37:52.217 に答える
0

それに対処するための「推奨される」方法はわかりませんが、より複雑な型への対処に関する質問に答えるには、次のようにします。

ComplexType foo()
{
    ...
    throw std::runtime( "Error..." );
    return *(ComplexType*)(0);
}

これは、任意の戻り値の型で機能します。私はそれが邪悪に見えることを認識していますが、警告を黙らせるためだけに存在します. あなたが言うように、このコードは実行されることはなく、最適化されることさえあります。

于 2011-04-12T15:39:46.493 に答える