プロが教えるわが家の防犯対策術!

以下のようなプログラムを組んでいます。

//main.h
static int hoge;
void someOperation();

//hoge.cpp
#include "main.h"
extern int hoge;

void someOperation()
{
hoge = 15;
}

//main.cpp
#include <stdio.h>
#include "main.h"
extern int hoge;

int main()
{
someOperation();
printf("%d\n",hoge);
return 0;
}

このプログラムを実行したのですが、自分の予想した15という出力ではなく、不定値になるようなのです。
自分の予想では、someOperationで操作するhogeも、main内で操作するhogeも同じになるようにと思いexternをつけているのですが、なにがまずいのでしょうか?
ご存知の方、ご教授お願いします。

A 回答 (2件)

結論から言えば、


static int hoge;
で、static をつけてはいけません。

この場合、hoge.cpp と main.cpp のどちらか一方に、
int hoge;

他方に、
extern int hoge;

が必要になります。

これを一括管理するテクニックとしては、以下のようなものが紹介されていました。

main.h

#if defined(GLOBAL_HERE)
#define EXT
#define DEF(x) = (x)
#else
#define EXT extern
#define DEF(x)
#endif

EXT int hoge;


main.cpp

#define GLOBAL_HERE
// この後で、inlude すると、EXT 指定した変数は、実態が宣言される
#include "main.h"

hoge.cpp
// こちらでは(ほかのファイルでも) GLOBAL_HERE は定義しない
#include "main.h"
// こちらでは、EXT 指定した変数は、 extern と読み替えられる

初期化が必要なときには、

EXT int hog DEF(10);

などとすると、
#define GLOBAL_HERE
のあとで include された場合は、
int hoge = (10);
そうでない場合には、
extern int hoge;
となります。
    • good
    • 0
この回答へのお礼

迅速な回答ありがとうございます。
確かにこの方法なら、一箇所に宣言をまとめられて気持ちがいいですね。
ありがとうございました。

お礼日時:2008/01/11 20:10

★まずいですね。


・まず main.h のヘッダファイルに static int hoge という変数の実体があります。
 結論から言うとこのような記述は避けるべきなのです。
 理由は
・hoge.cpp で main.h をインクルードしていますが、ここで hoge.cpp でしか使えない
 static int hoge が実体として作られます。これに 15 を代入していますが、static キーワードが
 付いているので他のソースファイル(main.cpp)からアクセスできません。見えないので。
・また main.cpp でも main.h をインクルードしていますが、こんどは main.cpp 用でしか使えない
 static int hoge が実体として作られます。つまり2つの hoge 変数が存在します。
・main.cpp では、この自分で見える hoge=0 が表示されます。
 決して hoge.cpp の hoge 変数ではありません。注意。

// hoge.cpp
static int hoge=15; ←main.cpp からは参照できない(隠されている)

// main.cpp
static int hoge=0; ←main.cpp ではこれを表示している

※hoge がそれぞれのソースファイルに1つずつ作られて合計2つあります。

解決策:
・main.h ヘッダには extern int hoge; のプロトタイプ宣言だけをします。
 そして hoge.cpp に extern int hoge=0; と定義します。
 そして someOperation() 関数内で hoge=15; とします。
・main.cpp では main.h をインクルードしますので『extern int hoge;』の
 記述は必要ありません。→あっても問題はありませんけど。

//main.h
extern int hoge;
void someOperation();

//hoge.cpp
#include "main.h"
extern int hoge = 0; ←※かならず何かの値を代入すること

void someOperation()
{
 hoge = 15;
}

//main.cpp
#include <stdio.h>
#include "main.h"

int main( void )
{
 someOperation();
 printf( "%d\n", hoge );
 return 0;
}
以上。
    • good
    • 0
この回答へのお礼

丁寧な回答ありがとうございます。
疑問が氷解しました。

お礼日時:2008/01/11 20:08

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!