ProgrammingC/組み込み開発者

Cにおける関数および変数の宣言と定義の違いを説明してください。これらのルールに違反した場合、マルチモジュールプロジェクトでは何が起こりますか?

Hintsage AIアシスタントで面接を突破

答え

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としてのみ宣言されており、初期化が行われているモジュールがなかったためです。これにより、ガベージデータの読み取りや埋め込みプラットフォーム上の捕らえ難いバグが発生しました。