web-dev-qa-db-ja.com

C / C ++グローバルと静的グローバル

可能性のある複製:
静的vsグローバル

グローバル変数と静的グローバル変数の違いについて混乱しています。 staticが、この変数が同じファイルに対してのみグローバルであることを意味する場合、2つの異なるファイルで同じ名前が名前の衝突を引き起こすのはなぜですか?

誰かがこれを説明できますか?

50
Vladp

リンカが他のファイルで使用できる.oファイルを作成すると、グローバル変数(staticではありません)が存在します。したがって、次のような2つのファイルがある場合、aで名前の衝突が発生します。

交流:

#include <stdio.h>

int a;

int compute(void);

int main()
{
    a = 1;
    printf("%d %d\n", a, compute());
    return 0;
}

紀元前:

int a;

int compute(void)
{
    a = 0;
    return a;
}

なぜなら、リンカは、使用するグローバルasのどれを知らないからです。

ただし、静的グローバルを定義するときは、そのファイルに対してのみ変数を保持し、リンカーに通知しないようにコンパイラーに指示します。したがって、私が書いた2つのサンプルコードにstaticを(aの定義で)追加すると、リンカはどちらのファイルにもaが存在することさえ知らないため、名前の衝突は発生しません。

交流:

#include <stdio.h>

static int a;

int compute(void);

int main()
{
    a = 1;
    printf("%d %d\n", a, compute());
    return 0;
}

紀元前:

static int a;

int compute(void)
{
    a = 0;
    return a;
}

つまり、各ファイルは、他のファイルを知らなくても、独自のaで動作します。


副次的な注意事項として、それらの1つがstaticであり、もう1つが異なるファイルにある限り、他のものであっても構いません。 2つの宣言が同じファイルにある場合(readtranslation unit)、1つのstaticと1つのexternthis answer

82
Shahbaz

各ファイルで静的な名前はnotで名前の衝突を引き起こすはずです。表示されている場合は、使用している正確なコンパイラとともに、それを示す(短い)デモコードを投稿してください。コードを適切に検証し、正しいと仮定してコンパイラを中傷します。

FWIWの場合、C++で推奨される方法は、代わりに匿名の名前空間を使用することです。

namespace { 
    int not_a_static_variable;
}

正直なところ、いや、それに対する客観的な利点の多くを指摘することはできません...

8
Jerry Coffin