C言語では、宣言(declaration)と定義(definition)を区別します。
例:
// 宣言(extern) extern int global_var; int func(int); // 定義 int global_var = 42; int func(int x) { return x * 2; }
マルチモジュールプロジェクトでは、宣言をヘッダーファイルに配置してモジュールが「互いに知る」ようにし、定義は1つのソースファイルのみで行い、リンキング時の競合を避けます。
同じ変数(例えば、int flag = 0;)の複数の同一定義が、同じヘッダーファイルをインクルードする異なるソースファイルに存在することはできますか?
答え: できません!ヘッダーファイルには宣言extern int flag;のみを含め、変数の定義は1つのソースファイル(int flag = 0;)にのみ行うべきです。これを遵守しないと、複数定義に関するリンカエラーが発生します。
物語
大規模プロジェクトで、グローバル変数をヘッダーファイルに
int counter = 0;として「分割」しました。このヘッダーをインクルードすることで定義の重複が発生しました。結果: CI/CDのビルド時にリンカエラー「multiple definition of counter」が発生しました。
物語
関数ライブラリで型を指定せずに関数のプロトタイプを作成し、コンパイラが古い宣言として処理し、その後、モジュール間で関数のシグネチャが一致しないというエラーが発生しました。
物語
テスト段階で一部の変数が初期化されていないことが判明しました。これは、
externとしてのみ宣言されており、初期化が行われているモジュールがなかったためです。これにより、ガベージデータの読み取りや埋め込みプラットフォーム上の捕らえ難いバグが発生しました。