noreturn "関数はなぜ戻るのですか?
質問
私が読んだのは
これ
についての質問
noreturn
属性についてです。これは呼び出し元に戻らない関数に使用されます。
では、C言語でプログラムを作ってみました。
#include <stdio.h>
#include <stdnoreturn.h>
noreturn void func()
{
printf("noreturn func\n");
}
int main()
{
func();
}
そして、このコードのアセンブリは この :
.LC0:
.string "func"
func:
pushq %rbp
movq %rsp, %rbp
movl $.LC0, %edi
call puts
nop
popq %rbp
ret // ==> Here function return value.
main:
pushq %rbp
movq %rsp, %rbp
movl $0, %eax
call func
なぜ関数
func()
を提供した後に
noreturn
の属性は?
どのように解決するのですか?
C言語の関数指定子は ヒント であり、どの程度受け入れるかは実装で決まります。
まず最初に
_Noreturn
関数指定子(または
noreturn
を使って
<stdnoreturn.h>
) は、コンパイラに
理論的な約束
をコンパイラに伝えるためのヒントです。この約束に基づいて、コンパイラは特定の判断を下し、コード生成のためにいくつかの最適化を行うことができます。
IIRCでは、もし関数が
noreturn
関数指定子で指定された関数が最終的に呼び出し元に戻る場合、どちらか一方は
-
を使い、明示的に
return
ステートメント - 関数本体の末尾に到達することで
その の動作は未定義です。 . あなたは はしてはいけません。 は関数から返してはいけません。
明確にするために
noreturn
関数指定子
は停止しません。
関数が呼び出し元に戻ることを止めません。これはプログラマがコンパイラに約束したもので、最適化されたコードを生成するために、コンパイラにある程度の自由度を与えるためのものです。
さて、先に約束をした後で、これに違反することを選択した場合、その結果は UB です。コンパイラは、警告を生成することが推奨されていますが、必須ではありません。
_Noreturn
関数が呼び出し元に戻ることが可能であるように見える場合、コンパイラは警告を出すことが推奨されています。
章§6.7.4によると
C11
, パラグラフ 8
で宣言された関数は
_Noreturn
関数指定子で宣言された関数は、その呼び出し元に戻ってはいけません。
と、12段落目の、( コメントに注意! )
EXAMPLE 2 _Noreturn void f () { abort(); // ok } _Noreturn void g (int i) { // causes undefined behavior if i <= 0 if (i > 0) abort(); }
について
C++
については、動作は非常に似ています。章§7.6.4から引用します。
C++14
を、段落2(
強調
)
もし、関数
f
が呼び出された場合f
は以前はnoreturn
属性とf
が最終的に が返された場合、その動作は未定義です。 [ 注意: この関数は例外を投げて終了することがあります。-終了 note ]です。[注意:実装では、もし
[[noreturn]]
を返すかもしれない場合、警告を出すことが推奨されます。 を返します。-注意の終わり ]。3 [ 例
[[ noreturn ]] void f() { throw "error"; // OK } [[ noreturn ]] void q(int i) { // behavior is undefined if called with an argument <= 0 if (i > 0) throw "positive"; }
-終了例 ]。
関連
-
[解決済み] stdinとSTDIN_FILENOの違いは何ですか?
-
[解決済み] C言語で%sを正しく使う - 超基本レベル
-
[解決済み] なぜGCCはa*a*a*a*aを(a*a*a)*(a*a*a)に最適化しないのでしょうか?
-
[解決済み] C言語では「?」演算子は何をするのですか?
-
[解決済み] 配列の場合、なぜ a[5] == 5[a] になるのでしょうか?
-
[解決済み] C言語における「static」の意味とは?
-
[解決済み] Cプリプロセッサはなぜ "linux "という単語を定数 "1 "と解釈するのですか?
-
[解決済み] プログラム終了前にmallocの後にfreeをしないと本当に何が起こるのか?
-
[解決済み] C言語のi++と++iに性能差はあるのでしょうか?
-
[解決済み】C言語の関数ポインタはどのように機能するのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
error: '.' トークンの前にunqualified-idを指定する必要があります。
-
g++が内部・外部コマンドソリューションとして認識されない、MinGWを初めて使うときの落とし穴
-
Solve Dev-c++ [エラー] 'for' ループの初期宣言は、C99 または C11 モードでのみ許可されます。
-
[解決済み] C言語の書式指定子 %ul と %lu の違いは何ですか?
-
[解決済み] Linuxカーネルにおけるcontainer_ofマクロの理解
-
[解決済み] C関数から文字列を返す
-
[解決済み] 演算子 *, /, +, -, % を使わずに 3 で割る。
-
[解決済み] longをフォーマットするprintfの引数は何ですか?
-
[解決済み】ノレターンのポイントとは?
-
[解決済み] なぜこのC++スニペットはコンパイルできるのか(非void関数が値を返さない) [duplicate]