C++ まとめ -言語編-

ページ内目録

ファイル

C++関連のファイル

  • ソースファイル
  • ヘッダファイル
  • 静的ライブラリ
  • 動的ライブラリ
  • プリプロセッサ
  • コンパイラ
  • アセンブラ
  • 静的リンカ
  • ローダ
  • 動的リンカ
  • デバッガ

高水準言語の多くは,プログラムを実行するために複数のファイルを使用する.ここではC++を例に説明を行う.

GCCがC++のファイルからプログラムを生成する場合,次のような流れで行われる.ここで,丸記号は言語処理系を,それ以外の記号はファイルの種類を表している.なお四角記号はバイナリファイルを表す.

各ファイルに関する詳細を以下に示す.

ファイル言語説明ファイル拡張子の例扱う者
ソースファイルC++とマクロプリプロセッサがマクロ部分が解読し,それに従った処理を施したファイルを生成する..cpp, .cxx, .C, .ccプリプロセッサ
ソースファイルC++とコンパイラ用の命令コンパイラが解読しアセンブリファイルを生成する..iiコンパイラ
ヘッダファイルC++とマクロヘッダファイルもまたソースファイルである.C++では,ヘッダに宣言文を記述し,前述のソースファイルに定義文を書く.プリプロセッサはソースファイルのマクロを解読した際にソースファイルに展開する.なし, .hプリプロセッサ
アセンブリファイルアセンブリとアセンブラ用の命令アセンブラが解読しオブジェクトファイルを生成する..sアセンブラ
オブジェクトファイル機械語オブジェクトファイルは,プログラムファイルやライブラリを作るために使用される..o静的リンカなど
静的ライブラリ静的リンカがプログラムファイルを生成するために使用する..a静的リンカ
動的ライブラリ機械語プログラム実行時に,動的リンカが動的ライブラリにある何かにアクセスした際にメモリ上に呼び出し,リンクする..so動的リンカ
プログラムファイル機械語プログラムは,OSの機能のローダによってメモリ上に読み込まれ実行される.なし, .out, .exeローダ

ライブラリ

ライブラリの作成

静的ライブラリと共有ライブラリはそれぞれ次のように行う。

静的ライブラリ
いくつかのオブジェクトファイルを圧縮したもの.
  1. オブジェクトファイルの生成。
    
    user% g++ -c object1.cpp -o object1.o
    
  2. ライブラリの生成。
    
    user% ar rv libtarget.a object1.o object2.o
    
動的ライブラリ
共有ライブラリ
複数のプロセスで利用されるライブラリのこと。プログラム実行中にロードされる。

user% g++ -fPIC -shared source1.cpp source2.cpp -o libtarget.so

ライブラリの使用

ライブラリは次のように使用される。


user% g++ -o a.out main.cpp -ltarget -L. -I.
各オプションはそれぞれ次のような意味を持つ。
-l
使用するライブラリを指定。
-L
ライブラリを検索する場所を追加
-I
ヘッダファイルを検索する場所を追加。
使用するライブラリやヘッダが,コンパイラがデフォルトで検索する場所にある場合,-lだけで良い。デフォルトでは,ライブラリの場所は/libや/usr/lib,ヘッダファイルの場所は/usr/includeが設定されている。これ以外の場所を指定する場合,-Lや-Iが必要である。使用するライブラリ間に依存がある場合,依存するファイルを外側に書く。例えばlibparent.aとlibchild.a,libgrandchild.aの3つのライブラリがあり,libchild.aがlibparent.aを,libgrandchild.aがlibchild.aを参照する時,次のような順番で-lを指定する。

user% g++ -o a.out main.cpp -lgrandchild -lchild -lparent -L. -I. 
また,動的ライブラリを使用する場合,コンパイラと動的ローダではライブラリを検索する場所が異なることに注意が必要である。この問題は次の3つのいずれかの方法で解決できる。
  • 検索場所(例:/libや/usr/libなど)にライブラリを移動
  • 検索場所を追加。検索場所は/etc/ld.so.confで設定されているので,それを修正。
  • 検索場所を追加。検索場所は環境変数でも追加可能である。

export LD_LIBRARY_PATH=.

C++では,templateやinline関数をサポートしている。templateの詳細は「ジェネリックプログラミング」,inline関数の詳細は「関数」で説明するが,それらの関数はコンパイルの際に処理を行う。それゆえ,これらをライブラリで定義してそれをインクルードして利用することはできない。templateについては,言語仕様でexportと呼ばれる指定子を付けることで別ファイルで定義できるとしているが,それらをサポートする言語処理系は多くない。inline関数については,GCCのようなコンパイラでは最適化を行う際に使用され,コードが展開されて外部ファイルから関数にアクセスできなくなる。それゆえ,外部ファイルからも使いたいような関数はinline化は避けたほうが無難である。このような問題があるため,外部ファイルでtemplateやinline関数を使用する場合,ヘッダファイルで定義される。ただし,本来ヘッダには定義を書くようなことはしないため,それに伴うエラーが発生することがある。例えばgccで-O0を指定して最適化を行わない場合,inline指定子は無視される。このような場合,通常の関数の定義と同様に扱われるため,インクルードした各ファイルでそれぞれ定義される。この時関数がstaticでない場合は,コンパイラは最終的に多重定義によるエラーを返す。


ファイルフォーマット

未完成-_-.

目録

キーワード

-緑の文字をクリック-