
どうもこんにちは
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を使用しなければならないのでしょうか?
No.1ベストアンサー
- 回答日時:
★『extern』をつけないと『extern』したのと同じになります。
>大域変数を他のファイルでも使用する場合はexternが必要ですが、
>関数に関してもexternを使用しなければならないのでしょうか?
↑
つけた方が分かりやすいと思います。
私はヘッダのプロトタイプ宣言や関数定義の時には『extern』や『static』を
付けて分かりやすくしています。関数定義の時に『extern』をつけておくと
あとで文字列の『extern』を含む行を取り出せば簡単にプロトタイプ宣言を
作成できるために関数定義の時も付けます。
・関数定義などでは『extern』、『static』を省略するとすべて『extern』に
なるため記述しなくても構いません。
ヘッダのプロトタイプ宣言にも『extern』を省略が可能です。
グローバル変数の場合は『extern』をつけた方がその変数の宣言と定義を
見分けられるためにつけた方が良いです。
・以上。参考に。
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;
}
といった(レアケースでしょうが)失敗を検出できなくなります。
回答ありがとうございます。
趣味で作成しているコードにはexternをつけていなかったのですが、仕事で変更しているコードで、既存のコードにexternが付いていたり、付いていなかったりして ( ̄_J ̄)ん? となりました。
省略ができるということなので、付けるかつけないかは既存のコードにあわせようと思います。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# Cのオブジェクトファイルの逆アセンブル 5 2023/05/13 01:51
- FX・外国為替取引 mql4のコンパイルエラー箇所の修正お願いします。 1 2023/03/15 16:14
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# const char** p;のとき、free(p)でC4090エラーとなるのはなぜですか 3 2023/03/31 16:28
- C言語・C++・C# C言語 3 2022/10/04 15:07
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
- C言語・C++・C# C言語のファイル入力が分かりません 2 2022/05/22 06:35
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
- C言語・C++・C# C言語: ポインタ 5 2022/06/01 08:33
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C++にてtemplateで受け取った任...
-
既定のコンストラクタがありま...
-
【gcc・cygwin】multiple defin...
-
多重定義が起きている?--lnk20...
-
const_castのつかいどころを教...
-
gcc: incompatible pointer type
-
【VC++6.0】イベントハンドラ関...
-
VC++でGetKeyboardStateがうま...
-
コールバックって・・・
-
unityの教科書のゲームを作って...
-
pic16f88とosl40562-lrとc言語...
-
C言語 プロトタイプ宣言
-
アドレス渡し?
-
typedef unsigned int UINT;が...
-
C言語 int main(void) main()
-
静的でないメンバ関数の呼び出...
-
メッセージマップ(ON_CONTROL_...
-
C++でオーバーロードに関するバ...
-
GDI+の使用方法について
-
_beginthreadにて発生するコン...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
静的でないメンバ関数の呼び出...
-
【gcc・cygwin】multiple defin...
-
戻り値を返す関数の前に(void)...
-
多重定義が起きている?--lnk20...
-
C++にてtemplateで受け取った任...
-
const_castのつかいどころを教...
-
既定のコンストラクタがありま...
-
C# Controls.Addで動的に配置し...
-
(void)0 はどんな意味ですか
-
C#でラジオボタンを設定に記録...
-
ウインドウの移動禁止
-
Notepad++の関数リスト表示の変...
-
Delphiの定数とローカル変数の...
-
typedef unsigned int UINT;が...
-
int main()、void main()、void...
-
C言語 extern について
-
void*型の配列について
-
VC++でGetKeyboardStateがうま...
-
_beginthreadにて発生するコン...
-
gcc: incompatible pointer type
おすすめ情報