9

「非常に読みやすい」「エレガントな」コードのこの「美しい」例に遭遇しましたが、それを理解するのに苦労しています:

struct S {

    [[noreturn]] virtual inline auto f(const unsigned long int *const)
                         –> void const noexcept;
};

これが私が理解していることです(間違っている場合は修正してください):

  • f()のメンバー関数ですS
  • virtual- 派生クラスによってオーバーライド可能
  • inline- コンパイラは、通常どおり呼び出すのではなく、呼び出し用のコードを生成しようとする必要がありますf
  • constS- 関数はのメンバーを変更できません
  • noexcept- 関数は決してスローしません (スローできないか、スローできない)
  • パラメータ:constへのポインタconst unsigned long int
  • auto .... -> void- 接尾辞の戻り型void
  • [[noreturn]]- それは決してありませreturn

ここに私の主な懸念事項があります:

  • 関数が として宣言されている場合、呼び出し元に戻る[[noreturn]]ことはありません。では、どのように戻り値の型を持つことができvoidますか? とにかく、この関数の戻り値の型のポイントは何ですか?
  • このコードは、たとえばintの代わりにコンパイルされますか?void
  • そのような関数の実用的な用途は何ですか? 例外をスローするには?
  • この関数の実行が終了した後 ( の後 )、コードの流れはどこに行き}ますか?

このコードを VS2013 Preview で実行することができなかったので、これらの機能はまだ実装されていなかったと思います。

とても気になるので、どなたか教えていただけると助かります!乾杯

4

4 に答える 4

19

[[noreturn]]、それが持つセマンティクスを持つ属性です。ただし、関数の宣言方法は変わりません。C++ のすべての通常の関数 (つまり、コンストラクタ、デストラクタ、および変換演算子を除くすべての関数) には、宣言された戻り値の型があります。属性を追加しても、このルールは変更されません。

この属性の目的は、[[noreturn]]おそらく、関数が通常の方法で決して戻らないことを示すことです。関数も宣言されていることを考えると、noexcept基本的に、対応する関数も例外をスローできないことを意味します。同様の動作をする関数の一例はexit()、プログラムを終了させる関数です。ある種のアプリケーション ループを実装する関数も資格があると想像できます。いずれにせよ、 は[[noreturn]]、対応する関数が正常に戻ることは決してないことをシステムに伝えます。つまり、関数から落ちる ("after }") と、未定義の動作が発生する可能性があります。

于 2013-08-21T07:50:35.890 に答える
6

関数が [[noreturn]] として宣言されている場合、関数は呼び出し元に戻りません。では、どのように戻り値の型を void にすることができますか? とにかく、この関数の戻り値の型のポイントは何ですか?

このQ&Aから、noreturn は、関数が返されないことをコンパイラに伝える方法であることがわかります。通常、これは、無限ループ (無期限に実行されることが想定されているサーバーでよく見られる) があるか、メインに戻らずにアプリケーションを終了するなどの呼び出しexit()を行うことを意味します。オプションです。つまり、指定する必要はありませ。これは属性です。つまり、関数を定義/宣言する基本的な構文は変更されないため、関数には他の関数と同様に戻り値の型が必要です。terminate()
[[noreturn]]

たとえば、このコードは void ではなく int でコンパイルされますか?

はい、そうなりますが、決して返らない関数から何かが返されても意味がないことをコンパイラが警告するかもしれません。

そのような関数の実用的な用途は何ですか? 例外をスローするには?

最初に頭に浮かぶのは、サーバーで着信要求を処理するなどの無限ループです。関数に対しても例外をスローする[[noreturn]]ことは問題ありませんが、明示的にnoexcept. スローすると への呼び出しがトリガーされstd::terminate()、プログラム自体が終了しますが、以前は実装で定義された量のスタックの巻き戻しが発生しました。これは、実際に[[noreturn]]はまだ適用可能であることを意味します。

この関数の実行が終了した後 ( } の後)、コードの流れはどこに行きますか?

関数が終了に達することはありません}。エンドレスに (誰かがプラグを抜くまで) 実行するか、プログラムの終了などによって異常終了します。つまり、関数がそれ以上実行されない場合、関数は実際には終了しておらず、実行を中止しており、プログラムも制御フローもありません。

于 2013-08-21T08:50:29.027 に答える