質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

209閲覧

Inline Expansion / Inlining ということ

退会済みユーザー

退会済みユーザー

総合スコア0

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2019/02/08 13:52

C++の入門者です。
表記の Inline Expansion に関する理解は、末尾に記したような内容で良いのですか?

IBMのサイト;
https://www.ibm.com/support/knowledgecenter/ja/SSLTBW_2.3.0/com.ibm.zos.v2r3.cbcpx01/inln.htm
では以下に引用するような説明がなされています。

(quote) インライン展開とは、ある特定の関数呼び出しをその関数の実際のコードで置き換えることであり、他のすべての最適化の前に実行されます。 サンプル・プログラムCCNGOP1 は、which_group() 関数について #pragma inline ディレクティブを指定しています。 CCNGOP1 をコンパイルするときに OPTIMIZE オプションを指定すると、コンパイラーは CCNGOP1 が CCNGOP2 と同じであると判断します。
//(quote) //サンプル・プログラム CCNGOP1 /* 最適化を示す例 */ #include <stdio.h> #pragma inline (which_group) int which_group (int a) { if (a < 0) { printf("first group¥n"); return(99); } else if (a == 0) { printf("second group¥n"); return(88); } else { printf("third group¥n"); return(77); } } int main (void) { int j; j = which_group (7); return(j); }
//(quote) //サンプル・プログラム CCNGOP2 /* 最適化を示す例 */ #include <stdio.h> int main(void) { printf("third group¥n"); /* a lot less code generation */ return(77); }

ということは、ある関数をinlineするということの順序は、

Preprocessorがcompilationの前に、inlined された関数をあらかじめ演算して、結果を得ておく。
その後に、
本来は、そのinlinedされた関数がcallされた後に、そのcallの結果としてreturnすべき値を、この値を表示するべき位置(すなわちcallerの位置)に表示する。
つまり、さらに簡潔に言えば、
preprocessorがcompilationの前に、前もって関数を演算しておいて、結果を表示しておく、

ということになりますか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

私にも分かりそうなサイトがありました。

[旧Nano/Classic]Arduino高速化テクニック②
http://gcraud.blog.jp/archives/42508770.html

inline関数をヘッダに書く際の注意点
http://d.hatena.ne.jp/white_wheels/20100318/p1

お世話になりました。

投稿2019/02/09 02:42

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

違います。関数の引数が定数だと誤解を招く虞がありますので、

C

1(前略) 2int main (int argc, char **argv) { 3 int x; 4 int j; 5 6 x = atoi(argv[1]); 7 j = which_group (x); 8 9 return(j); 10}

というプログラムがあると、これは下記と同等になります。

C

1//(quote) 2//サンプル・プログラム CCNGOP1 3 4/* 最適化を示す例 */ 5 6#include <stdio.h> 7#include <stdlib.h> 8 9int main (int argc, char **argv) { 10 int x; 11 int j; 12 13 x = atoi(argv[1]); 14 15 if (x < 0) { 16 printf("first group¥n"); 17 j = 99; 18 } 19 else if (x == 0) { 20 printf("second group¥n"); 21 j = 88; 22 } 23 else { 24 printf("third group¥n"); 25 j = 77; 26 } 27 28 return(j); 29}

また、インライン展開は、プロプロセッサが処理するのでは無くて、Cコンパイラが処理します。

引数が定数の場合は、一旦上記と同様に展開されて、最適化フェーズでif( 7 < 0)のような条件部が偽の部分の処理が削除されるでしょう。

本筋と関係ありませんが、return(j);return j;と書くのが普通です。また、関数名と引数を囲む括弧の間には空白を空けないのが普通です。

投稿2019/02/08 14:19

otn

総合スコア84551

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/02/08 14:33 編集

お世話になります。 >関数の引数が定数だと誤解を招く虞があり これはどういうことですか、入門まぎわで私にはやや難解です。
otn

2019/02/08 16:39

if( 7 < 0) のような普通書かないコードが出てくるので、理解しにくいかと思いました。 理解しにくくなければ、定数でも問題ありません。
退会済みユーザー

退会済みユーザー

2019/02/08 23:50 編集

otnさん、おはようございます。 お世話になります。昨日の件(上記)は70%程度理解できた感があります。 しかし、せっかく書いていただいたotnさんのサンプルプログラムは、IBMさんのものより私には難しいのでまだ理解できません。 //otnさんのサンプル(引用) x = atoi(argv[1]); j = which_group (x); と関数が渡されるような書き方まで、私の理解が進んでいないからです。 私が引用したIBMさんのサンプルは、otnさんのものより簡易なので、これで説明されたらもう少し分かるのではないかと考えます。 IBMさんのサンプルに従った私の理解は次の通りです。この理解に誤りがあればご案内お願いします。 1:CCNGOP1のmainで int main (void) { int j; j = which_group (7); なので、which_group() に 7 を渡す。 2:渡された 7 が else {} に該当するので 77 がreturnされる。 3:上記2の結果と //サンプル・プログラム CCNGOP2 /* これも最適化を示す例 */ #include <stdio.h> int main(void) { printf("third group\n"); /* a lot less code generation */ return(77); } は同じ処理になっている。 4:すなわちこの処理は、 //IBMさんの説明(引用) インライン展開とは、ある特定の関数呼び出しをその関数の実際のコードで置き換えることであり、他のすべての最適化の前に実行され という意味になっている。
otn

2019/02/09 00:04

4は正しいです。 その文章を100%理解しているのならOKです。 3はその最適化後の話ですね。 私が、 > 最適化フェーズでif( 7 < 0)のような条件部が偽の部分の処理が削除されるでしょう。 と書いたのは理解できていますか? ただ、 x = atoi(argv[1]); が難しいということは、入門書の先頭10%くらいに書いてあるレベルが理解できていない状態で、インライン展開を理解しようとするのは早いのでは?
退会済みユーザー

退会済みユーザー

2019/02/09 00:31

お世話になります。 私のチャレンジが早いか、早くないか、という教育者的視点は私には興味がありません。いま、手元にあるどうしても利用したいプログラムを理解するために、分からないことを知る努力をしているだけです。 具体的には、Arduino用のHeader file にあるcodingで、 static inline void timer_start(void){TCCR4B = startTCCR4B;TIMSK4 = (1<<TOIE4);} や、 static inline void timer_shutdown(void){TCCR4B = 0;TIMSK4 = 0;OCR4C = saveOCR4C;} などがあるので、これを理解しなければならないのです。 >if( 7 < 0)のような条件部が偽の部分の処理が削除される というのは上述2で渡したargument「7」については、「7<0」はfaulseだから、これはreturnされない、というと理解しました。これでは不足ですか?
episteme

2019/02/09 01:50 編集

> static inline void timer_shutdown(void){TCCR4B = 0;TIMSK4 = 0;OCR4C = saveOCR4C;} > などがあるので、これを理解しなければならないのです。 inline でなければ、理解できますか? inlineであろうがなかろうが、行われることは同じです。 inlineだとそのtimer_shutdownを呼ぶんじゃなくて、 呼び出したその位置に {TCCR4B = 0;TIMSK4 = 0;OCR4C = saveOCR4C;}を直接書き下したのと同じことになります。 # 関数呼び出しを行わない分ほんのちょっと速い。
退会済みユーザー

退会済みユーザー

2019/02/09 02:40

epistemeさん、お世話になります。 以前もアドバイスいただきました。アレから1ヶ月経ちました。 この上記に例示の部分は、AVRのRegistorを設定する部分だろうと推察しています。 Inline化について、私にも分かりそうなサイトがありました。 [旧Nano/Classic]Arduino高速化テクニック② http://gcraud.blog.jp/archives/42508770.html inline関数をヘッダに書く際の注意点 http://d.hatena.ne.jp/white_wheels/20100318/p1 2つ目が詳細に書いていてくれて、これから詳しく学びます。 もう少し学んできますので、またよろしくお願いします。
otn

2019/02/09 05:02

プログラムの処理内容理解というのが目的だと、epistemeさんのコメントの通り、インラインかどうかは無視して良いです。 なので、てっきり、インライン関数とは何かを理解したいという質問かと思っていました。
退会済みユーザー

退会済みユーザー

2019/02/09 05:41 編集

otnさん、お世話になりました。 入門したばかりで、質問だってさぞかし下手にみえたのだろとおもいます。込み入ったことが分かるようになったらまたお願いします。お付き合い頂きありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問