[dcl.attr.noreturn]は、次の例を提供します。
[[ noreturn ]] void f() {
throw "error";
// OK
}
[[noreturn]]
しかし、関数の戻り値の型が既に であるため、のポイントがわかりませんvoid
。
それで、noreturn
属性のポイントは何ですか?どのように使用することになっていますか?
[dcl.attr.noreturn]は、次の例を提供します。
[[ noreturn ]] void f() {
throw "error";
// OK
}
[[noreturn]]
しかし、関数の戻り値の型が既に であるため、のポイントがわかりませんvoid
。
それで、noreturn
属性のポイントは何ですか?どのように使用することになっていますか?
noreturn属性は、呼び出し元に戻らない関数に使用されることになっています。これは、void関数(呼び出し元に戻る-値を返さない)を意味するのではなく、関数の終了後に制御フローが呼び出し元の関数に戻らない関数(たとえば、アプリケーションを終了する関数、永久ループするか、例のように例外をスローします)。
これは、コンパイラーがいくつかの最適化を行い、より適切な警告を生成するために使用できます。たとえば、がnoreturn属性を持っている場合、コンパイラは、を記述したときにデッドコードであるf
ことを警告する可能性があります。同様に、コンパイラは、の呼び出し後にreturnステートメントが欠落していることを警告しないことを認識します。g()
f(); g();
f()
noreturn
関数が値を返さないことをコンパイラに伝えません。これは、制御フローが呼び出し元に戻らないことをコンパイラーに伝えます。これにより、コンパイラはさまざまな最適化を行うことができます。呼び出しの周りの揮発性状態を保存および復元する必要がなく、呼び出しに続くコードをデッドコードで削除できます。
これは、機能が完了しないことを意味します。への呼び出しの後に、制御フローがステートメントにヒットすることはありませんf()
。
void g() {
f();
// unreachable:
std::cout << "No! That's impossible" << std::endl;
}
この情報は、さまざまな方法でコンパイラ/オプティマイザによって使用できます。g()
コンパイラは、上記のコードに到達できないという警告を追加できます。また、継続をサポートするなど、さまざまな方法で実際のコードを変更できます。