現在3つのファイルにわけて1つのプログラムを書いています。
3ファイルで1つの変数Counterを共有したいのです(どのファイルからもアクセスできる)が方法がわかりません
以下の状態でコンパイルすると
Error: 外部シンボル '_Counter' が未解決
とでてきます。
なにか解決方法はありますでしょうか?それとも根本からおかしいのでしょうか?
===========main.c=============
#include "sub.h"
int Counter;
=============================
============sub.h============
#include "subsub.h"
extern int Counter;
=============================
============subsub.h=========
extern int Counter;
=============================
externで他のファイルから見えるようにする方法
Re: externで他のファイルから見えるようにする方法
3つのファイルと書かれていたので、てっきり3つの.cファイルかと思いました。
今のコードは、main.cで
extern int Counter;
extern int Counter;
int Counter;
と書いたのと実質的に同じです。
本当にそういうことがしたいのでしょうか。
今のコードは、main.cで
extern int Counter;
extern int Counter;
int Counter;
と書いたのと実質的に同じです。
本当にそういうことがしたいのでしょうか。
Re: externで他のファイルから見えるようにする方法
3つのファイルというのは、main.c, sub.h, subsub.hの3つのことですか?
アプリをビルドする過程は大体次のようになっています。
この3段階をまとめて「コンパイル」と言う場合もあります。
main.cのみですね。sub.hとsubsub.hはプリプロセスの段階でmain.cに展開されますからね。
そして、main.cの(狭義の)コンパイルは可能です。
一般に、(狭義の)コンパイル時には、「シンボル未解決」のエラーは出ません。
シンボル未解決のエラーが出るのはリンクのときです。リンクするときにはじめて
外部シンボルの解決が行われます。
(printf関数を使ったプログラムの場合、printf関数もこのときにリンクされます。)
したがって、「Error: 外部シンボル '_Counter' が未解決」のエラーが発生するとするなら
リンク時なのですが、残念ながらあなたの示したファイル群ではこのエラーは出ないのです。
main.cにint Counter;がありますからね。
(しかし、main関数が未解決なのでリンク自体は失敗します。)
想像なのですが、sub.hとかsubsub.hを(狭義の)コンパイルしようとしているのではないですか?
それならば、extern int Counter;しかしていないので、(狭義の)コンパイルはできません。
アプリをビルドする過程は大体次のようになっています。
この3段階をまとめて「コンパイル」と言う場合もあります。
- プリプロセス
- (狭義の)コンパイル
- リンク
main.cのみですね。sub.hとsubsub.hはプリプロセスの段階でmain.cに展開されますからね。
そして、main.cの(狭義の)コンパイルは可能です。
一般に、(狭義の)コンパイル時には、「シンボル未解決」のエラーは出ません。
シンボル未解決のエラーが出るのはリンクのときです。リンクするときにはじめて
外部シンボルの解決が行われます。
(printf関数を使ったプログラムの場合、printf関数もこのときにリンクされます。)
したがって、「Error: 外部シンボル '_Counter' が未解決」のエラーが発生するとするなら
リンク時なのですが、残念ながらあなたの示したファイル群ではこのエラーは出ないのです。
main.cにint Counter;がありますからね。
(しかし、main関数が未解決なのでリンク自体は失敗します。)
想像なのですが、sub.hとかsubsub.hを(狭義の)コンパイルしようとしているのではないですか?
それならば、extern int Counter;しかしていないので、(狭義の)コンパイルはできません。
Re: externで他のファイルから見えるようにする方法
ご回答ありがとうございます。
生半可な知識でexternを誤解してしまっていました。
ヘッダファイルに実装する場合とソースファイルに実装する場合の違いを
理解せず書いていました。
ヘッダファイルはコピーと同じ事なので、わざわざexternしなくてよいのですね。
誤解がとけたのでこれにて解決とさせて頂きます。
細かいミスですみません。
ありがとうございました。
生半可な知識でexternを誤解してしまっていました。
ヘッダファイルに実装する場合とソースファイルに実装する場合の違いを
理解せず書いていました。
ヘッダファイルはコピーと同じ事なので、わざわざexternしなくてよいのですね。
誤解がとけたのでこれにて解決とさせて頂きます。
細かいミスですみません。
ありがとうございました。
Re: externで他のファイルから見えるようにする方法
コンパイルに通るのでsubsub.hに
int Counter
と書いてしまいました・・・
危険なのでしょうか?
int Counter
と書いてしまいました・・・
危険なのでしょうか?
Re: externで他のファイルから見えるようにする方法
危険と言うか、リンク時に問題が発生します。shiro4ao さんが書きました:コンパイルに通るのでsubsub.hに
int Counter
と書いてしまいました・・・
危険なのでしょうか?
以下、具体例で説明します。
ヘッダファイルhoge.hに と書いて、そのヘッダファイルをfoo.c, bar.cでincludeしたとしましょう。
foo.c bar.c すると、プリプロセスが終了した段階で次のようになりますね。
foo.c bar.c 次にfoo.cとbar.cを(狭義の)コンパイルします。
(狭義の)コンパイルは、.cファイル1つずつに対して行われることに注目してください。
すると、オブジェクトファイルfoo.oとbar.oにそれぞれ、_Counterというシンボルが生成されます。
この状態でfoo.oとbar.oをリンクしようとすると、どちらの_Counterを使っていいのか
分からないというわけです。
だから普通はこうします。
hoge.h foo.c bar.c 要するに、ヘッダではexternで「宣言」し、どれか一つのcファイルで「定義」するようにします。
Re: externで他のファイルから見えるようにする方法
具体的な説明ありがとうございます。
人間がファイル1つ1つをちゃんと把握しておかないといけないのですね。
ファイルに分けたら便利かと思いましたが、
1人で作るぶんには無意味に分割しないほうがよさそうですね。
人間がファイル1つ1つをちゃんと把握しておかないといけないのですね。
ファイルに分けたら便利かと思いましたが、
1人で作るぶんには無意味に分割しないほうがよさそうですね。
Re: externで他のファイルから見えるようにする方法
ファイル分割は無意味ではないですよ。
ガシガシ分割して、コンパイルの仕組みを学習しましょう!
ガシガシ分割して、コンパイルの仕組みを学習しましょう!
Re: externで他のファイルから見えるようにする方法
将来、ファイル分割する可能性もあるので
すこしづつでも勉強していきたいと思います。
すこしづつでも勉強していきたいと思います。