インライン関数について考える


一個前の投稿ではCの仮引数付きマクロについて取り上げたけど、本題はC++のインライン関数だったり。
仮引数付きマクロでは()で正しく演算順序を指定しないと問題が起きがちですよ、と。
で、CからインクリメントしたC++ではそれを一歩上行くインライン関数と言う物があり、より関数に近い形で置換できると言う優れもの。
使い方は以下の通り。

#include <iostream>
using namespace std;
#define PI 3.141592674
inline double area_of_circle(double r)
{
return r * r * PI;
}
int main()
{
double radius;
cout << "円の半径を入力して下さい。\n";
cin >> radius;
cout << "円の面積は" << area_of_circle(radius - 1.0 + 1.0) << "です。\n";
return 0;
}

実行結果は以下の通り

McLaren% ./inline_test
円の半径を入力して下さい。
4
円の面積は50.2655です。

18行目のように、わざと計算を挟んでみた。
仮引数付きマクロならば

radius - 1.0 + (1.0 * radius) - 1.0 + (1.0 * PI)

となるところを、

(radius - 1.0 + 1.0) * (radius - 1.0 + 1.0) * PI

と言うように、パーレンで囲わなくてもコンパイラが適宜最適化してくれると言う仕組み。
型の指定をしていることからわかる通り、型もチェックしてくれます、と。
これは便利。

ただ、独習C++によると

inline指定子は、コンパイラにとってはコマンドではなく要求であることを覚えておいてください。

とのこと。
どうやらループとか書いてあるとダメなコンパイラもあるらしい。
ただ、普及しているコンパイラはOKっぽい?
そもそも自分で明示的にインライン関数にするのは好ましくないから、コンパイラが自動的にインライン化する機能を有しているので、それに任せた方が良いんだとか。
ん〜、さすが後発言語。
何から何まで便利。

で、インライン化できなかった場合は普通の関数になるらしい。
ここで疑問になるのがプロトタイプ宣言の是非なんだけど、Wikipediaによれば

インライン関数はモジュール単位に定義する必要がある(通常の関数は1つのモジュールで定義すればよい)。これにより、モジュール単位に独立したコンパイルができるようになっている。

となる。
と言うことは、モジュール単位で書くのが当然で、外部から呼び出すのは無理?もしくはナンセンス?
一応ちょっと試したんだけど、ヘッダに書いたら読める。
ただ、別ソースファイルに書いたら読めなかった。
なるほど、独立しているとはそう言うことなのか??

一応動くソースは下記の通り。
(文字列を渡すところで警告あり。でも動く。)

inline_test_main.cpp

#include <iostream>
#include "inline.h"
using namespace std;
int main()
{
double radius;
echo("円の半径を入力して下さい。");
cin >> radius;
cout << "円の面積は" << area_of_circle(radius) << "です。\n";
return 0;
}

inline.h

#include <iostream>
using namespace std;
#define PI 3.141592674
void echo(char []);
inline double area_of_circle(double r)
{
return r * r * PI;
}

inline.cpp

#include "inline.h"
void echo(char str[])
{
cout << str << endl;
}

コンパイルと実行結果は下記のとおり。

McLaren% g++ -o inline inline_test_main.cpp inline.cpp
inline_test_main.cpp: In function ‘int main()’:
inline_test_main.cpp:9: 警告: deprecated conversion from string constant to ‘char*’
McLaren% ./inline
円の半径を入力して下さい。
3
円の面積は28.2743です。

そんだけ。

Post to Twitter

, , , ,

  1. No comments yet.
(will not be published)