ページ 11

extern宣言と定義について

Posted: 2012年7月16日(月) 14:28
by atori
C言語についてはある程度理解しているつもりだったのですが、ファイル分割で躓いています。

とあるヘッダでextern宣言を行い、全てのcファイルでそのヘッダをインクルードしています。

その場合、どのcファイルでもいいのでextern宣言を行った変数を定義をすれば、変数の共有は可能という認識だったのですが、
エラーで弾かれてしまいます。(よくある外部参照が未解決というエラーです)

この認識が間違っていれば、ご指摘願えますでしょうか。

補足までに、使用している環境はVisual Studio 2008です。

Re: extern宣言と定義について

Posted: 2012年7月16日(月) 15:10
by softya(ソフト屋)
どこかのcppで実体の定義は行われているのでしょうか?
※ externのない変数宣言です。

Re: extern宣言と定義について

Posted: 2012年7月16日(月) 15:18
by atori
他のcファイルでexternした変数に値を入れています。
これでは実体化されないのでしょうか?

Re: extern宣言と定義について

Posted: 2012年7月16日(月) 15:33
by softya(ソフト屋)
atori さんが書きました:他のcファイルでexternした変数に値を入れています。
これでは実体化されないのでしょうか?
extern は実体を作らず外部にある実体を参照する変数であると言う意味になります。
なので、どこかのc/cppファイルに実体は必要です。

>externした変数に値を入れています。
代入と宣言は全く関係ありません。
もしローカル変の定義と初期化のことを言っているならグローバル変数には無関係です。

Re: extern宣言と定義について

Posted: 2012年7月16日(月) 15:36
by MoNoQLoREATOR
"extern"をつけずに普通に宣言した変数が実体になります。
main関数があるcファイルで実体を宣言することをおすすめします。

h1.h

コード:

extern int var; //extern宣言
main.c

コード:

#include "h1.h"

int var; //実体宣言

int main(){}
あと、"extern"をつけた場合代入しちゃダメですよ。
たしかコンパイルエラーにはならなかったと思いますが代入は行われません。


最後に、こう言ってはナンですが、グローバル変数というものは、そうそう使うものではありませんよ。
main関数で宣言して、引数を使ってやり取りするか、関数内static変数を使うべきです。
特に、関数内static変数が使える状況ならば積極的に使っていくべきだと思います。
もっとも、Cはクラスが使えないわけですから、グローバル変数を使った方がすっきりする場合もありますから、一概にどうとは言えませんが。

Re: extern宣言と定義について

Posted: 2012年7月16日(月) 16:40
by atori
MoNoQLoREATOR さんが書きました:"extern"をつけずに普通に宣言した変数が実体になります。
main関数があるcファイルで実体を宣言することをおすすめします。
MoNoQLoREATORさんのソースを元に改変してみました。
私のソースの場合次のような処理をしています。


h1.h

コード:

extern int var[]; //extern宣言
main.c

コード:

#include "h1.h"

int var[]; //実体宣言

int main(){
    var[] = {{0},{1},{2}}; //初期化
}
このvar[]変数を別のファイル(h1.hはインクルード済み)で使用しようとした場合に"外部参照が未解決"とエラーが出ました。
softya(ソフト屋)さんが言っていたように実体の宣言を入れてみても変わりないです。

問題点を指摘していただけないでしょうか。

Re: extern宣言と定義について

Posted: 2012年7月16日(月) 16:49
by softya(ソフト屋)
main.cに関してはこうすればOKです。

コード:

#include "h1.h"
int var[]= {0,1,2};	//実体と初期化

int main(){
}
元の問題。
int var[];だけだと大きさ不明なので定義できません。
var[] = {{0},{1},{2}};初期値代入は実体の定義時にしかできません。スカラ変数に対して{0}は文法的にNGです。

Re: extern宣言と定義について

Posted: 2012年7月16日(月) 17:02
by atori
エラーが消え無事実行することができました。

MoNoQLoREATORさん
softya(ソフト屋)さん
ありがとうございました。