
No.7ベストアンサー
- 回答日時:
> というのは、最適化をせずに、明示的にインライン指定をしなくても自動でインライン展開(可能な限り)をしてくれるということですね。
> 逆にCでは最適化をするかインライン指定をしないとインライン展開(可能な限り)をしてくれないということですか?
ちょっと違います。
確かに、明示的にinlineを付けなくても、最適化でインライン展開されることはありますが、ここで取り上げているのはinlineというキーワードの意味についてです。
C++ではinlineを付けた関数はインライン展開を目指すのに対して、Cではinlineを付けた関数は高速呼び出し(実現方法は任意)を目指すというわけです。
> > プロセッサ依存の関数ベクタ
> よく分からないので勉強します
通常、関数を呼び出すには16~64ビット程度のアドレスを指定する必要があります。それを、関数ベクタ(関数のアドレスを集めたテーブル)に予め登録しておき、何番目の関数というように(ハード的に)指定すれば、もっと効率よく関数を呼び出せます。
他には、絶対アドレスではなく、相対アドレスで指定すれば、関数呼び出しを効率化できる可能性があります。
私自身プログラミングは上位アプリケーションしか作ったことがなく、インライン展開も「オプティマイザで出来ればインラインしとこう」くらいでした。
分からないキーワードがたくさん出てきたのでもっと勉強します。
とても参考になりました。ありがとうございました。
No.6
- 回答日時:
#3です。
私がアセンブラを組んでいたときは、OSがプロセスに割り当てたメモリの下位番地がスタックに割り当てられるので、特別スタックをプログラマが意識する必要はなかったように思います。今は変わっているんですかね。
ただ自動的に割り当てられたスタックには限りがありますので、再帰の階層が深くなりすぎると、スタックオーバーフローのエラーが出ますので、そのときは、プログラムをリンクする段階でスタック領域を確保できるようにたいていのコンパイラはなっていました。
No.5
- 回答日時:
末尾再帰の場合にはループに展開できる可能性があることは既に回答が出ている通りです。
他に、再帰関数の引数の一部が定数であれば、関数の定義次第ではインライン展開できる可能性があります。
もし、引数の全部が定数であれば、単なる右辺値になったり、関数内での副作用の部分だけが直接インライン展開される可能も、「原理的には」考えられます。
> C以外の言語でも、再帰関数のインライン展開が出来るプログラム言語があれば教えてください。
C++とか(多分期待している答えは違うんでしょうね)。
C言語もC99でinlineが標準でサポートされるようになりましたが、C++のinlineとは微妙に仕様がことなります。
C++では文字通り(可能な限り)インライン展開させるための機能ですが、C99では(可能であれば)通常より高速に呼び出す方法を採用させるための機能です。それはインライン展開でもよいですし、プロセッサ依存の関数ベクタを使ったり、ハード的な機能を利用したり、関数の定義によって方式を選択したりしても構わないわけです。
C言語とC++とではインライン展開の仕様が違うんですか。
> C++では文字通り(可能な限り)インライン展開させるための機能
というのは、最適化をせずに、明示的にインライン指定をしなくても自動でインライン展開(可能な限り)をしてくれるということですね。
逆にCでは最適化をするかインライン指定をしないとインライン展開(可能な限り)をしてくれないということですか?
> プロセッサ依存の関数ベクタ
よく分からないので勉強します
ありがとうございました。
No.4
- 回答日時:
普通はできないです。
引数の受け渡しによる値の保持をするスタックを自前で作ればいいのかもしれませんが、なにやってんだかわかんないですよね。
それに、もしインライン展開できるとしても、インライン指定した関数がコンパイラによってインライン展開されるかどうかはわかりません。
もともとできるかぎりインラインにしてねという指定だからです。
大抵の場合、再帰関数はループに置き換えできると思うので、初めからループとしてコーディングした方がいいと思います。
自前でスタックを作るのは訳が分からなくなりそうですね。関数コールのオーバーヘッドが気になるようなら素直にループ構造に置き換えたほうがいいですね。
No.3
- 回答日時:
長い間アセンブラでプログラムを組んでいないので、自信ありませんが、再帰関数の場合、スタックで引数のやり取りをするぐらいで、他の処理は普通の関数と同じだったと思います。
No.2
- 回答日時:
一般論として、再帰関数は次のような方法によるインライン展開が可能です。
(1) あらかじめ決めた数段分だけ展開する
例えば「f()がf()を呼ぶ」かわりに、f()のコピーを2つ作成しておき「f()がf2()を、f2()がf3()を、f3()がf3()を呼ぶ」ように展開します。(常にこのような展開が可能なわけではありません。)
すると、f()→f2()とf2()→f3()の各呼び出しは再帰ではない普通の関数呼出になるので、f()とf2()は通常の関数と同様のインライン展開が可能になります。
このような形にすることで、ループアンロールと同様のメリットがあります。
(2) 「終端再帰関数」を単純ループに置き換えて展開する
終端再帰関数とは、関数実行の最後で再帰呼出を行う再帰関数のことです。このような形の関数の場合、これを再帰ではなく単純ループの形に書き換えることが可能です。(常に可能なのか、あるいは正確にはどのようにして「終端再帰」を見分けるのか、という厳密な定義は知りません。)
ですので、再帰関数が終端再帰関数であれば、単純ループに置き換えた上で通常の関数と同様のインライン展開が可能になります。
(1)では階乗計算などで実現できそうですね。
(2)ではインラインで出来ない再帰構造は「終端再帰」に変えた方がいいということですね。(オーバーヘッド軽減のため)
「終端再帰」というのがよく分からないので勉強してみます。
ありがとうございました。
No.1
- 回答日時:
普通はできないです。
ただし、いわゆる末尾再帰は、ループに展開できます。
Lisp,Schemeなどの関数型言語では、ほぼ必須の機能です。
C++等では、実現している処理系と思いますが。
末尾再帰でないループは、スタックを自前で作ることでループに展開できますが、これを自動的にやってくれる最適化機能は、多分ないと思います。
> いわゆる末尾再帰は、ループに展開できます。
末尾再帰がよく分からないので勉強します。
末尾再帰に修正したい場合は自力で修正しないといけないんですね。
関数設計時に末尾再帰を頭に入れておかないといけないですね。
ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- 数学 高一数学 数と式 画像あり (2)までは出来たのですが、 (3)の下線部の文字式の展開が理解できませ 2 2023/08/19 15:48
- 数学 複素関数と実関数のテーラー展開の違いについて 1 2022/08/09 06:18
- 数学 多変数関数の微分とテイラー展開について 5 2022/04/24 16:55
- 数学 f(θ)=sinθ/cosθに関して、 f(θ)=sinθ/cosθをθ=π/2のまわりでローラン展 4 2022/09/17 19:11
- 物理学 フーリエ級数展開をExcelのFFTでシミュレートする 5 2023/07/03 22:02
- C言語・C++・C# プログラム内から、MIDIファイルの一部分だけを再生する方法 1 2023/02/15 11:08
- C言語・C++・C# C言語 3 2022/10/04 15:07
- 数学 フーリエ級数展開の問題 1 2022/11/04 10:57
- 英語 「再び」の接頭辞”re-"を有する単語と文末に"again"を付けた表現のニュアンスに違いについて 1 2022/12/13 12:40
- 数学 「f(z)=1/(z^2-1)に関して ローラン展開を使う場合、マクローリン展開を使う場合、テイラー 3 2022/08/27 19:56
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・一番好きなみそ汁の具材は?
- ・泣きながら食べたご飯の思い出
- ・「これはヤバかったな」という遅刻エピソード
- ・初めて自分の家と他人の家が違う、と意識した時
- ・いちばん失敗した人決定戦
- ・思い出すきっかけは 音楽?におい?景色?
- ・あなたなりのストレス発散方法を教えてください!
- ・もし10億円当たったら何に使いますか?
- ・何回やってもうまくいかないことは?
- ・今年はじめたいことは?
- ・あなたの人生で一番ピンチに陥った瞬間は?
- ・初めて見た映画を教えてください!
- ・今の日本に期待することはなんですか?
- ・集中するためにやっていること
- ・テレビやラジオに出たことがある人、いますか?
- ・【お題】斜め上を行くスキー場にありがちなこと
- ・人生でいちばんスベッた瞬間
- ・コーピングについて教えてください
- ・あなたの「プチ贅沢」はなんですか?
- ・コンビニでおにぎりを買うときのスタメンはどの具?
- ・おすすめの美術館・博物館、教えてください!
- ・【お題】大変な警告
- ・洋服何着持ってますか?
- ・みんなの【マイ・ベスト積読2024】を教えてください。
- ・「これいらなくない?」という慣習、教えてください
- ・今から楽しみな予定はありますか?
- ・AIツールの活用方法を教えて
- ・最強の防寒、あったか術を教えてください!
- ・歳とったな〜〜と思ったことは?
- ・モテ期を経験した方いらっしゃいますか?
- ・好きな人を振り向かせるためにしたこと
- ・スマホに会話を聞かれているな!?と思ったことありますか?
- ・それもChatGPT!?と驚いた使用方法を教えてください
- ・見学に行くとしたら【天国】と【地獄】どっち?
- ・これまでで一番「情けなかったとき」はいつですか?
- ・この人頭いいなと思ったエピソード
- ・あなたの「必」の書き順を教えてください
- ・14歳の自分に衝撃の事実を告げてください
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
画面を強制的に再描画させる方法
-
アクティブセルから、A列最終行...
-
Escキーを押すと、中断する時と...
-
EXCEL VBA ユーザーフォームの...
-
WinAPI「MsgWaitForMultipleObj...
-
Do whileでExitせず、ループの...
-
VB2010でCSVファイルの読み込み
-
DOSコマンドのループ内のTIMEコ...
-
データベースをEOFまでループさ...
-
メッセージループを調べすぎてC...
-
UWSCの終了の仕方
-
vb.netです。2次元配列の要素を...
-
エクセルの当番表を作っていま...
-
乱数の桁数指定、または範囲指定。
-
レインボー色ってどうやって表...
-
VBA for i=1 to lastrow
-
UDP:送信レートについて
-
流れ図(フローチャート)が分か...
-
VBS オーバーフローの原因
-
CSVファイルの特定の行だけを読...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
画面を強制的に再描画させる方法
-
UWSCの終了の仕方
-
VBAでの一時停止と再開の方法
-
範囲指定したセルを1つずつ飛...
-
Escキーを押すと、中断する時と...
-
VBAで3秒だけ時間を止めたい
-
DoEventsが必要な理由について
-
vb.netです。2次元配列の要素を...
-
乱数の桁数指定、または範囲指定。
-
DOSコマンドのループ内のTIMEコ...
-
CSVファイルの特定の行だけを読...
-
VBA for i=1 to lastrow
-
エクセルの当番表を作っていま...
-
UWSCに制限時間を付けたいです
-
Do whileでExitせず、ループの...
-
vb.netからエクセル関数書き込み
-
null 参照の例外が実行時に発生...
-
VB.NETで素因数分解のプログラ...
-
イベントの発生を待つ
-
GIFアニメをループさせたくない
おすすめ情報