externで他のファイルから見えるようにする方法

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
アバター
shiro4ao
記事: 224
登録日時: 15年前
住所: 広島

externで他のファイルから見えるようにする方法

#1

投稿記事 by shiro4ao » 14年前

現在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;
=============================

初級者
記事: 200
登録日時: 15年前

Re: externで他のファイルから見えるようにする方法

#2

投稿記事 by 初級者 » 14年前

3つのファイルと書かれていたので、てっきり3つの.cファイルかと思いました。
今のコードは、main.cで
extern int Counter;
extern int Counter;
int Counter;
と書いたのと実質的に同じです。
本当にそういうことがしたいのでしょうか。

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: externで他のファイルから見えるようにする方法

#3

投稿記事 by beatle » 14年前

3つのファイルというのは、main.c, sub.h, subsub.hの3つのことですか?

アプリをビルドする過程は大体次のようになっています。
この3段階をまとめて「コンパイル」と言う場合もあります。
  1. プリプロセス
  2. (狭義の)コンパイル
  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;しかしていないので、(狭義の)コンパイルはできません。

アバター
shiro4ao
記事: 224
登録日時: 15年前
住所: 広島

Re: externで他のファイルから見えるようにする方法

#4

投稿記事 by shiro4ao » 14年前

ご回答ありがとうございます。
生半可な知識でexternを誤解してしまっていました。

ヘッダファイルに実装する場合とソースファイルに実装する場合の違いを
理解せず書いていました。
ヘッダファイルはコピーと同じ事なので、わざわざexternしなくてよいのですね。

誤解がとけたのでこれにて解決とさせて頂きます。
細かいミスですみません。
ありがとうございました。

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: externで他のファイルから見えるようにする方法

#5

投稿記事 by beatle » 14年前

本当に解決ですか?
くれぐれもヘッダファイルに

コード:

int Counter;
とか書かないでくださいね。

アバター
shiro4ao
記事: 224
登録日時: 15年前
住所: 広島

Re: externで他のファイルから見えるようにする方法

#6

投稿記事 by shiro4ao » 14年前

コンパイルに通るのでsubsub.hに
int Counter
と書いてしまいました・・・
危険なのでしょうか?

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: externで他のファイルから見えるようにする方法

#7

投稿記事 by beatle » 14年前

shiro4ao さんが書きました:コンパイルに通るのでsubsub.hに
int Counter
と書いてしまいました・・・
危険なのでしょうか?
危険と言うか、リンク時に問題が発生します。
以下、具体例で説明します。

ヘッダファイルhoge.hに

コード:

int Counter;
と書いて、そのヘッダファイルをfoo.c, bar.cでincludeしたとしましょう。

foo.c

コード:

#include "hoge.h"
bar.c

コード:

#include "hoge.h"
すると、プリプロセスが終了した段階で次のようになりますね。

foo.c

コード:

int Counter;
bar.c

コード:

int Counter;
次にfoo.cとbar.cを(狭義の)コンパイルします。
(狭義の)コンパイルは、.cファイル1つずつに対して行われることに注目してください。
すると、オブジェクトファイルfoo.oとbar.oにそれぞれ、_Counterというシンボルが生成されます。

この状態でfoo.oとbar.oをリンクしようとすると、どちらの_Counterを使っていいのか
分からないというわけです。


だから普通はこうします。
hoge.h

コード:

extern int Counter;
foo.c

コード:

#include "hoge.h"
int Counter;
bar.c

コード:

#include "hoge.h"
// ここでは int Counter; を書かない
要するに、ヘッダではexternで「宣言」し、どれか一つのcファイルで「定義」するようにします。

アバター
shiro4ao
記事: 224
登録日時: 15年前
住所: 広島

Re: externで他のファイルから見えるようにする方法

#8

投稿記事 by shiro4ao » 14年前

具体的な説明ありがとうございます。

人間がファイル1つ1つをちゃんと把握しておかないといけないのですね。
ファイルに分けたら便利かと思いましたが、
1人で作るぶんには無意味に分割しないほうがよさそうですね。

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: externで他のファイルから見えるようにする方法

#9

投稿記事 by beatle » 14年前

ファイル分割は無意味ではないですよ。
ガシガシ分割して、コンパイルの仕組みを学習しましょう!

アバター
shiro4ao
記事: 224
登録日時: 15年前
住所: 広島

Re: externで他のファイルから見えるようにする方法

#10

投稿記事 by shiro4ao » 14年前

将来、ファイル分割する可能性もあるので
すこしづつでも勉強していきたいと思います。

閉鎖

“C言語何でも質問掲示板” へ戻る