extern宣言とは
extern宣言とは、外部のファイルで定義した変数を使用する際、コンパイラに対して「このファイルは外部で定義済みの変数です」と宣言するために使用する。
関数の外部で定義された変数はグローバル変数と呼ばれ、システム全体(プログラム全体)で参照可能な変数として扱われる。そのため、あるファイル内で定義したグローバル変数は別ファイルで使用することができる。
しかし、例えば以下のようにmain.cで宣言、定義した変数g_hogeをsub.cで参照するとコンパイルエラーが発生する。
/* グローバル変数g_hogeを宣言&定義 */
int g_hoge = 0;
void sub(void);
int main (void)
{
sub();
return 0;
}
#include <stdio.h>
void sub(void)
{
printf("g_hoge = %d¥n",g_hoge);
return;
}
コンパイルエラーが発生する理由は、コンパイルはファイル単位で実施されるため、sub.cをコンパイルする際にコンパイラがg_hogeのシンボル定義を見つけられないからである。
g_hogeはmain.cで宣言、定義済みのため、その旨をコンパイラに伝えることができればコンパイルは通りそうである。
そこで使用するのがextern宣言である。
main.cで宣言、定義済みのg_hogeをコンパイラに通知するため、sub.cでextern宣言を以下のように行う(ここでextern int g_hoge = 1のように定義を行うことはNG。あくまでexternは宣言を行うためのものであり、定義時には使用しない)。
これによりコンパイラがg_hogeの存在を認識し、sub.cでg_hogeが使用可能になる。
#include <stdio.h>
extern int g_hoge;
void sub(void)
{
printf("g_hoge = %d¥n",g_hoge);
return;
}
externの宣言場所
extern宣言は一般的にヘッダファイル上で行う。g_hogeをmain.c以外のファイル上で使用したい場合、extern宣言が記述されたmain.hをインクルードすることによってg_hogeの存在が知らされるため使用可能になる。
#include "main.h"
/* グローバル変数g_hogeを宣言&定義 */
int g_hoge = 0;
void sub(void);
int main (void)
{
sub();
return 0;
}
#ifndef MAIN_H
#define MAIN_H
extern int g_hoge;
#endif
#include <stdio.h>
#include "main.h"
void sub(void)
{
printf("g_hoge = %d¥n",g_hoge);
return;
}
上記の通り、基本的なexternの使用方法としては以下の通りである。
・あるソースファイル内(※)でグローバル変数(g_hogeとする)を定義する。
・g_hogeが定義されたソースファイルがインクルードしているヘッダファイル上でg_hogeのextern宣言を行う。
・extern宣言したヘッダファイルをインクルードしたソースファイル内でg_hogeを使用する。
(※)グローバル変数の定義をヘッダファイル上で行わないようにする。ヘッダファイルで定義した場合、そのヘッダファイルが複数ファイルから参照されていると、変数の複数定義となるためリンク時にエラーが発生する。