• ベストアンサー

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を使用しなければならないのでしょうか?

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

  • ベストアンサー
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.1

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

redasurc
質問者

お礼

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

その他の回答 (1)

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.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; } といった(レアケースでしょうが)失敗を検出できなくなります。

redasurc
質問者

お礼

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