ProgrammingC 開発者

C言語における変数と関数のstaticとexternの違いを説明してください。スコープがモジュールの構成にどのように影響するか?

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

答え

  • static(ファイル/モジュールレベル):

    • staticとして宣言された変数や関数は、そのコンパイルモジュール(ファイル)にスコープが制限されます。
    • この関数/変数は他のソースファイルでは「見えません」。
  • extern

    • 他のモジュールで定義された関数/変数を宣言するために使用されます。コンパイラに「この変数/関数は別の場所にあります」と知らせます。

重要: staticは実装の隠蔽用、externはモジュール間のリンク用。

例:

main.c:

static int hidden_var = 5; extern int shared_var; int main() { printf("shared %d", shared_var); }

shared.c:

int shared_var = 10;

他のファイルからhidden_varを使用しようとすると、リンクエラーが発生します。

ひねりのある質問

異なるモジュールで異なる修飾子static/externを持つ同じ名前の変数を定義した場合、何が起こりますか?

答え: 各static変数(例えば、異なるファイルのstatic int foo;)は完全に独立したオブジェクトです。extern int foo;の宣言は、名前がfooの共有グローバル変数を探します。staticとexternを混合することはできません—これは、あるファイルでfooがstaticとして定義され、別のファイルでexternとして宣言されると、リンクエラーを引き起こします。

トピックの細かい知識が原因の実際のエラーの例


物語 プロジェクトで、異なるモジュールに同じ名前の関数が重複していることが発見されました(staticなし)。リンカーはそのうちの1つしかリンクせず、もう1つは「失われ」、アプリケーションのロジックに影響を与えました。


物語 大規模プロジェクトで、int counter;というグローバル変数が2つのモジュールに宣言されましたが、どちらもexternなしで行われました。その結果、アプリケーションの動作はリンクの順序に依存し、時折競合するシンボルが発生しました。


物語 モジュールはスコープが誤って定義された関数を使用していました:それはstaticとして定義されており、開発者は別のソースからそれを呼び出そうとしました—プログラムはexternに修飾子を変更するか(またはstaticを削除しない限り)構築されませんでした。