35202


最近「inline」という仕組みを知り色々と調べているのですが、[ロベールのC++教室](http://www7b.biglobe.ne.jp/~robe/cpphtml/html02/cpp02008.html)や[Qoosky](https://www.qoosky.io/techs/753fec0d4e)等の記事では「inline関数の実装はヘッダに記述する」と記述があります(ロベールではクラスの宣言と記述はありますが)。

ここで一つ確認なのですが、これは

> コンパイル時に処理を埋め込む際に埋め込む内容が明らかである必要であり、故にヘッダーに実装内容が記述されているべきである。

という解釈でよろしいのでしょうか。

また、以前inlineを試しに使ってみようとしたところ、誤っていつも通りcpp側に実装を記述してしまいましたが一応問題なく動いていました。

しかしこれはコンパイル時に

>   1. 全.h読み込み...
>   2. コンパイラ「おい！ inline関数の中身がねぇぞ！」
>   3. 全.cpp読み込み...
>   4. コンパイラ「ここにあるじゃねえか！」
>   5. 再度.cpp読み込んでinline関数呼び出し側に埋め込み...
>

という(私の勝手なイメージの)流れによりcppを読み込むオーバーヘッドが生まれている為無駄であるという事になるのでしょうか。

よろしくお願いいたします。


CC BY-SA 3.0
2017-06-01T23:26:49.660
35201
2017-06-02T01:00:26.777
20642
question
c++
inline関数の実装はヘッダファイルでというのは何故？


> コンパイル時に処理を埋め込む際に埋め込む内容が明らかである必要

はい、そう考えてＯＫです。別の理由は ODR (One Definition Rule)
で、インラインとした関数が複数の翻訳単位で異なる内容であることを防ぐために同一ヘッダファイル中にある同一の関数定義を使うためでもあります。

JIS X 3014:2003 7.1.2 関数指定子

> `inline` 指定子は [snip] インライン置換をするのが望ましいことを指示する。

望ましいだけで「しなければならない」義務付けはされていないので

> いつも通りcpp側に実装を記述してしまいましたが一応問題なく動いていました。

というのはごく普通（言語規格書に合致した正しい挙動）です。インライン宣言されている関数の関数定義が関数利用時点で明らかになっていない場合、インライン展開せずに通常の関数呼び出し手続きが生成されます。あるいは、インライン展開すると逆効果である（サイズ優先最適化指示と反するなど）とコンパイラが判断した場合にも同様。

提示の「勝手なイメージ」動作は、言語規格書上の「翻訳単位」という概念からいくと、行わないことが定められています。言語仕様を逸脱してでも高度最適化を優先する処理系では、行うかもしれませんが、オイラの使っている組み込み系コンパイラ複数種類のどれも、そのような最適化は行っていません。


CC BY-SA 3.0
2017-06-02T00:22:22.500
35202
2017-06-02T00:22:22.500
8589
35201
answer


コンパイラーはオブジェクトファイルを生成し、リンカという別のツールが複数のオブジェクトファイルを結合して実行ファイルを生成します。ですので、

>   5. 再度.cpp読み込んでinline関数呼び出し側に埋め込み...
>

というようなステップとはならず774RRさんが回答されているように通常の関数呼び出しとして結合されます。

しかし、

  * [GCCのLTO; Link Time Optimization](https://gcc.gnu.org/onlinedocs/gccint/LTO.html)
  * [ClangのLTO; Link Time Optimization](http://llvm.org/docs/LinkTimeOptimization.html)
  * [Visual C++のLTCG; Link Time Code Generation](https://msdn.microsoft.com/ja-jp/library/xbf3tbeh.aspx)

など、コンパイラーとリンカが協調してリンク時に最適化を行うことがあります。コンパイラーが最適と判断すればリンク時に再コンパイルが行われインライン展開が行われます。  
（組み込み系コンパイラとは状況が違うということかな？）


CC BY-SA 3.0
2017-06-02T01:00:26.777
35204
2017-06-02T01:00:26.777
4236
35201
answer