はC11

2012-12-03 10 views
13
で_Noreturnの使用

可能性の重複:
What is the point of the Noreturn attribute?はC11

C11は、関数が戻ることはないことを示すために_Noreturn属性を導入しました。

ソースコードの文書化の価値を除いて、その属性が提供する他のメリットとその理由は何ですか?

+1

http://stackoverflow.com/questions/10538291/what-is-the-point-of-the-noreturn-attributeはC++に対して同じ質問をします。 Cの推論はまったく同じです。 –

+3

推論も同様です。構文はC++( '[[noreturn]])とC(' _Noreturn'や ''をインクルードした場合は 'noreturn')の間で全く違うように見えます。ですから、私はそれを良いx-refと見なします。しかし、私は重複については分かりません。 –

+2

これはCについてのもので、もう1つは完全に異なる2つの言語に関するC++に関するものであるため、再オープンのために推薦します。実際の構文も非常に異なります。 –

答えて

18

関数は無条件_Noreturn関数を呼び出す場合、コンパイラはそれを理解することができるようになります:

  • 最適化が可能デッドコードは次のコードは、(それが生成されたバイナリから削除することができます)および診断 - コンパイラは「到達不能なコード」警告を発することができます。
  • 関数からの通常のフローが中断されたことを知っていると、戻り値の欠落、初期化されていない変数などに関する偽の警告を避けることができます。

    これは、静的コードアナライザでは特に重要である - 私たちはnoreturnとして私達のdie機能(致命的なエラーを記録し、アプリケーションを終了する)をマークしたら、私たちの大きめのアプリケーションで打ち鳴らす静的アナライザによって与えられた偽陽性の数が大幅に低下しました。

も利用できるいくつかの他の最適化があるかもしれません - 関数が戻ることはないため、スタック上のリターンアドレスをプッシュする必要はありません、レジスタと何の状態を保存し、必要だとすべてが渡すことです戻り値と戻り値のクリーンアップを心配することなく、関数の最初にjmpを実行します。もちろん、コールがワンショットなので、ここで絞り込むパフォーマンスはほとんど無視できます。

+0

この引数では、返される関数であっても_Noreturnとしてマークすることができます。例: 'int foo(data * arg){++ arg-> count;リターンバー(arg); } ' - 関数fooはジャンプで呼び出され、次にデータが実際に返されるbar()に再びジャンプすることができます。それとも、私はポイントを逃したのですか? – user666412

+0

@ user666412:テールコールの最適化です。これはほとんど無関係です。'_Noreturn'を' bar'に適用すると、* never *が返されます。 OTOHの場合、ここでコンパイラはある特定のインスタンスで単に 'bar'にクリーンアップを委譲するかもしれません。また、私の答えは最適化の側面を強調しすぎています( '_noreturn'関数にとってはあまり意味がありません)。その主な目的は、デッドコードをマークし、そのような環境の警告をより適切に調整することです呼び出し(例えば、 'exit(1)'を行う関数を持っている場合、戻り値を返すかどうかは関係ありません)。 –

+0

これは、プログラム内で最大でも1回発生するコールにはまだ多すぎるようです。 – user666412

0

これにより、コンパイラによる追加の最適化が可能になります。

static __attribute__((noreturn)) void die(const char *fmt, ...) { 
    /* print a formatted error message and exit */ 
    exit(EXIT_FAILURE); 
} 
/* And let's say in main() you would want to exit because of an error but unforunately GCC complains about return value. */ 
int main() 
{ 
    if (!whatever) 
     die("a nasty error message goes here\n"); 
} 

そしてまた、などの最適化のために使用されます(セマンティクスはおそらく同じである)、それは今しばらくサポートGCCのnoreturn属性を見hereしてください

4

__attribute__((noreturn))または_Noreturndie()のように機能するのに便利です述べました。

+0

[JFYI] main()関数から明示的に "返す"必要はありません(これはC互換の残っています) – AlexT

+0

何が起こるのかを実証するための単なる例でした。 –

関連する問題