こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

C言語 extern について

どうもこんにちは
C言語でプログラムを作っています。

複数のファイルから1つのプログラムを作っていますが、あるファイルで実装した関数を別のファイルから使用する際、単にプロトタイプ宣言を行うだけでなく、extern が必要なのでしょうか?

今までは extern を使用せず、以下のように書いてました。
// main.c ファイル
int func_sub();
int func_main()
{
return func_sub() * 2;
}

// sub.c ファイル
int func_sub()
{
return 10;
}

これは extern を使用して、このように書かないとだめなのでしょうか?
// main.c ファイル
extern int func_sub(); // このexternは必要?
int func_main()
{
return func_sub() * 2;
}

// sub.c ファイル
int func_sub()
{
return 10;
}

大域変数を他のファイルでも使用する場合はexternが必要ですが、関数に関してもexternを使用しなければならないのでしょうか?

投稿日時 - 2007-10-10 10:11:39

QNo.3416848

暇なときに回答ください

質問者が選んだベストアンサー

★『extern』をつけないと『extern』したのと同じになります。
>大域変数を他のファイルでも使用する場合はexternが必要ですが、
>関数に関してもexternを使用しなければならないのでしょうか?
 ↑
 つけた方が分かりやすいと思います。
 私はヘッダのプロトタイプ宣言や関数定義の時には『extern』や『static』を
 付けて分かりやすくしています。関数定義の時に『extern』をつけておくと
 あとで文字列の『extern』を含む行を取り出せば簡単にプロトタイプ宣言を
 作成できるために関数定義の時も付けます。
・関数定義などでは『extern』、『static』を省略するとすべて『extern』に
 なるため記述しなくても構いません。
 ヘッダのプロトタイプ宣言にも『extern』を省略が可能です。
 グローバル変数の場合は『extern』をつけた方がその変数の宣言と定義を
 見分けられるためにつけた方が良いです。
・以上。参考に。

投稿日時 - 2007-10-10 11:00:03

お礼

回答ありがとうございます。

省略可能ということなので、既存のコードにスタイルをあわせようと思います。

投稿日時 - 2007-10-11 09:39:16

このQ&Aは役に立ちましたか?

79人が「このQ&Aが役に立った」と投票しています

回答(2)

ANo.2

結論からいうと、extern指定子は不要ですが、付けた方が若干ケアレスミスの検出能力は上がります。

記憶クラス指定子無しで宣言した関数は、同じ翻訳単位内で、記憶クラス指定子を伴った同じ関数の宣言がない限り、外部結合になります。
具体的には、

extern void foo(void);
static void bar(void);

void foo(void); /* ← 外部結合 */
void bar(void); /* ← 内部結合 */

のように、同じ関数を複数宣言すると、相互に補完しあう仕様なのです。
そのため、もしextern指定子を付けていないと、

void foo(void); /* ← 外部結合のつもり */

static void foo(void) {} /* 内部結合として定義 */

int main()
{
 foo(); /* 他の翻訳単位で定義されたfooを呼び出したつもりが、そうならない */
 return 0;
}

といった(レアケースでしょうが)失敗を検出できなくなります。

投稿日時 - 2007-10-10 11:34:52

お礼

回答ありがとうございます。

趣味で作成しているコードにはexternをつけていなかったのですが、仕事で変更しているコードで、既存のコードにexternが付いていたり、付いていなかったりして ( ̄_J ̄)ん? となりました。
省略ができるということなので、付けるかつけないかは既存のコードにあわせようと思います。

投稿日時 - 2007-10-11 09:43:49

あなたにオススメの質問