2016-04-01 14 views
2

私はハンドルを取得して使用しようとしています([[noreturn]]C++11 standard attributeで、__attribute__((noreturn))はGCC/Clang拡張です)、[[noreturn]]属性でちょっと遊んでいます。これの一環として、私はClangの警告を有効にしました。疑わしい場合のClang警告:関数 'foo'は属性 'noreturn'で宣言できますか?

> clang++ -v 
Ubuntu clang version 3.7.1-svn253742-1~exp1 (branches/release_37) (based on LLVM 3.7.1) 
Target: x86_64-pc-linux-gnu 
Thread model: posix 

foo.cpp:次に

enum bar 
{ 
    A = 1, 
    B, 
    C 
}; 

void foo() 
{ 
    switch (bar()) 
    { 
    case A: 
    case B: 
    case C: 
    default: 
     break; 
    } 
} 

int main() 
{ 
    foo(); 
    return 0; 
} 

コンパイル:

> clang++ foo.cpp -o foo -Wmissing-noreturn -std=c++14 
foo.cpp:9:1: warning: function 'foo' could be declared with attribute 'noreturn' 
     [-Wmissing-noreturn] 
{ 
^ 
1 warning generated. 

それが戻ってくるように私には見えます!何が起きてる?これはコンパイラのバグですか?

Aから「= 1」を削除すると、警告なしで正常にコンパイルされます。

foo()関数を[[noreturn]] void foo()にすると、セグメント化エラーでクラッシュします。

+2

私にはバグのように見えます。 –

+0

Apple(XCode) 'clang ++'(バージョン情報 'Apple LLVM version 7.3.0(clang-703.0.29)' 'ターゲット:x86_64-apple-darwin15.4.0' 'スレッドモデル:posix')で再現できます。 。私はまだそれを解釈できるかどうかわからない - 'enum'のデフォルトのコンストラクタは何を返しますか?あなたのコードでは、bar()は0を返すように見えます - これは面白いですが、関数が返ってこないことを意味するものではありません) –

+0

@JonathanLeffler - 良い質問です。私がそれを "A = 0"にすると、警告は出ません。私は以前と同じように動作するenumクラスで遊んでいました。おそらくデフォルトでは常に0に初期化されています。これは無効で、デフォルトに落ちるのではなくトラップになりますか?または未定義の動作ですか? –

答えて

-1

大変申し訳ございませんが最後の回答です。それは間違っていました。関数が決して終わらないことを確認してください。バーは変数ではないため、分割が必要です

+0

属性 'noreturn'(装飾されています)は、この関数が呼び出されると、コントロールの流れが関数から返ってこないことを意味します。これは通常、exit()や_exit()などのプログラムを停止するような関数を呼び出すことを意味します。サンプルコードでは、 'foo()'の中から呼び出される唯一の関数は 'bar()'です。これは 'enum bar {...};型のデフォルトのコンストラクタです。それがなぜ返されないのかはすぐに分かりません。もしそうなら、関数 'foo()'が返されるので、 'noreturn'属性は不適切です。 –

関連する問題