SolarisとLinuxのグローバル変数の扱いについて
Solaris用のソースをLinuxで使えるように変更したいのですが、
グローバル変数について以下のようなことが発生していて困っています。
なにか、コンパイルオプションなどで対応はできないものでしょうか?
Solaris (CC)では
特にextern宣言しなくても同じシンボルの外部変数はコモンセグメントに1つだけ作成しコンパイル自体は正常である。
しかし、Linux (g++)では
externを宣言しないと同じシンボルを再定義したことになりエラーとなる。
これにより、グローバル変数を多用しているプログラムはLinuxでうまくコンパイルができない。
しかし、単純にextern宣言での対応は難しい。
extern宣言は外部で定義してあるグローバル変数を参照する
というものだがLinux では
1つの定義を意外は全てexternしなければ、2重定義エラーになってしまう。
つまり、実体が1つであとはそれを参照しているという形でなければいけない。
ところが、その実体をどこにするか特定することができない。
例えば、gというグローバル変数を仮定する。
A.c,B.c,C.cはその3つのソースよりAA.aという静的ライブラリを構成する。
gはA.cで定義してありB.c,C.cはそれを参照する。
ところが
C.cは個別にC.oというオブジェクトで他からの呼び出しがあり
別LMにリンクされる。
その時C.c内のgは実体を失うことになり未定義となる。
つまり、どれが実体になるかは何にリンクするかで決まるため
実態を特定できない。
また、共通のヘッダにグローバル変数が定義されている場合も、重複するというエラーを起こすため、
共通ヘッダからグローバル変数を分離し、何れかのソースにグローバル変数の実態を定義させる必要がある。
共通ヘッダを使っている他のソースはそのグローバル変数の実態を参照するようにexternの宣言をする。