2016-07-18 11 views
12

noreturn属性は決して返されない関数に必要ですか、これはちょうど(おそらく時期尚早ですか? - 少なくとも出口については、私はそこで最適化する理由を想像できません)最適化ですか?終了関数のnoreturn属性は必要ですか?

このような

void myexit(int s) _Noreturn { 
    exit(s); 
} 
// ... 
if (!p) { myexit(1); } 
f(*p); 
/// ... 

noreturnなどのコンテキスト内で最適化されてから!p枝を防止することを私に説明しました。 しかし、コンパイラがその分岐を最適化することは本当に許されていますか? p == NULLの場合、逆参照はUBなので、pはこのコンテキストではNULLになることはありません。したがって、!pブランチはトリガしません。」というメッセージが表示されることがあります。しかし、コンパイラは、myexitが(明示的にそのようにマークされていなくても)返されない関数であると仮定することによって問題を解決することはできませんか?

+0

私はC++にマークを付けることを躊躇しています。しかし、C++にはnoreturn属性( '' [noreturn] ')もあり、C/C++の答えが大歓迎です。 – PSkocik

+2

_ "noreturnは'!p'ブランチが最適化されないようにします。 " – mvidelgauz

+0

可能な複製 - http://stackoverflow.com/questions/10538291/what-is-the-point-of-noreturn – mvidelgauz

答えて

7

これにより、いくつかの最適化が行われます。第1に、呼び出し自体のために、これは単純化されたセットアップを可能にし、すべてのレジスタを保存する必要はないが、callまたは類似の命令の代わりにjmp命令を使用することができる。通常のフローへの分岐が戻ってこないので、呼び出し後のコードを最適化することもできます。

はい、通常_Noreturnはコンパイラにとって貴重な情報です。

あなたの質問への直接的な答えとして、いいえ、これは最適化のためのプロパティなので、はではありません。

+2

ありがとうございますが、それは質問に答えません。 – PSkocik

+1

@PSkocik、私の編集を参照してください。 –

+1

@JensGustedtそれほど詳細ではありませんが、少なくとも今質問の主要な部分に答えています;-) – PSkocik

2

公理:標準ゆえassertが明確に定義されている使用して、C.

  • 標準はassertを指定するには、明確に定義されているもので、明確なリソースです。
  • assertは、abort_Noreturnという関数を条件として呼び出します。したがって、これは許可されています。
  • assertの使用方法はすべて関数内にあります。したがって、関数が返される場合もありません。
  • 標準は、この例があります

    _Noreturn void g (int i) { // causes undefined behavior if i <= 0 
        if (i > 0) abort(); 
    } 
    

    したがって条件付き_Noreturnあってはならない返す関数。 これは意味:外部で定義された機能については

    • 、コンパイラが返されない場合があります機能を想定しており、「内部的に」定義された関数についてはif -branch
    • を最適化する自由はありませんが、コンパイラができますその関数が常にブランチを返すか最適化するかどうかを確認してください。どちらの場合も

は、コンパイルされたプログラムの動作は非最適化抽象Cマシンはどうなるのかと整合すると「として-場合は、」ルールが観察されます。

+0

証拠の一種としてそれを書いていると思うのはクールだし、今それを見て、私はもう確信していません。しかし、それは私が考える質問に答えます。 :-)それをより正式にするために編集してください。 – a3f

+1

コンパイラは、外部定義関数が返されないと仮定することはできません。その代わりに、関数が返されるケース(関数の後に続くコードは省略できません)とそうでないケースの両方を処理するように準備する必要があります(関数の後に続くコードは、関数や何かの実行に影響を与えませんその前に)。 – supercat

+0

@supercat、それに言い直してください。ありがとう。 – a3f

関連する問題