C++でのグローバル変数の宣言

解決


さる  2003-05-21 00:35:57  No: 51434  IP: [192.*.*.*]

こんばんは。
複数のソースファイルから使用できる変数の宣言についてですが、
プロジェクト内に
main.cpp
sub.cpp
main.h
とあるとき、main.cppとsub.cppの両方で使用できる変数g_abcを、
main.hに
int g_abc;
のように宣言し、main.cppとsub.cppでmain.hをインクルードしてビルドすると、
"int g_abcはすでにsub.objで定義されています
 1 つ以上の複数回定義されているシンボルが見つかりました"
とエラーが出てしまいます。
Cだとこれでよかったと思ったのですが、CとC++では
宣言の仕方が違うのでしょうか。
どなたかよろしくお願いします。

編集 削除
YuO  2003-05-21 10:10:49  No: 51435  IP: [192.*.*.*]

> 複数のソースファイルから使用できる変数の宣言についてですが、
> プロジェクト内に
> main.cpp
> sub.cpp
> main.h
> とあるとき、main.cppとsub.cppの両方で使用できる変数g_abcを、
> main.hに
> int g_abc;
> のように宣言し、main.cppとsub.cppでmain.hをインクルードしてビルドすると、
> "int g_abcはすでにsub.objで定義されています
>  1 つ以上の複数回定義されているシンボルが見つかりました"
> とエラーが出てしまいます。

C++標準(ISO/IEC 14882:1998)の3.2 One definition ruleの3より。
>Every program shall contain exactly one definition of every non-inline function or object that is used in that program; no diagnostic required.

C標準(JIS X 3010:1993)の6.7 外部定義より
>外部結合で宣言した識別子を式(sizeof演算子のオペランドである場合を除く。)の中で使用する場合,プログラム全体のどこかにその識別子に対する外部定義が必ず一つなければならない。使用しない場合,二つ以上あってはならない。

C標準(ISO/IEC 9899:1999)の6.9 External definitionの5より
>If an identifier declared with external linkage is used in an expression (other than as part of the operand of a sizeof operator whose result is an integer constant), somewhere in the entire program there shall be exactly one external definition for the identifier; otherwise, there shall be no more than one.

JIS X 3010だと曖昧ですが,ISO/IEC 14882:1998や同9899:1999では外部定義は一つにする必要があります。
というわけで,どちらかで定義して,もう一方では宣言だけにするとよいです。

ヘッダファイルには,通常
extern int g_abc;
のように外部宣言のみを書きます。

編集 削除
さる  2003-05-21 11:39:14  No: 51436  IP: [192.*.*.*]

宣言と定義を区別せずに考えていました。
よく考えてみれば関数はどこかに定義しておいて、実際使うファイルに
プロトタイプ宣言しますよね。
YuOさんありがとうございました。勉強になりました。

編集 削除