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の宣言をする。
お礼
>クリティカルセクション等でガードすれば問題なく使えます。 なるほど、グローバル変数・関数と同じように衝突しないように気をつけろということですね。 C言語の記述をVCに書いては、という話だったんですね。 勘違いして、Cのみで作成しては、という話かと思ってしまいました。理解不足でした。 ヒープということは、mallocとかをつかってメモリ確保しては?という話なのでしょうか?