Подтвердить что ты не робот

C/С++ global vs static global

Возможный дубликат:
Статические и глобальные

Я запутался в различиях между глобальными и статическими глобальными переменными. Если static означает, что эта переменная является глобальной только для одного и того же файла, то почему в двух разных файлах одно и то же имя вызывает конфликты имен?

Может кто-нибудь объяснить это?

4b9b3361

Ответ 1

Глобальные переменные (не static) существуют, когда вы создаете файл .o, доступный для компоновщика, для использования в других файлах. Поэтому, если у вас есть два таких файла, вы получаете столкновение имен на a:

a.c:

#include <stdio.h>

int a;

int compute(void);

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

b.c:

int a;

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

потому что компоновщик не знает, какой из глобальных a использовать.

Однако, когда вы определяете статические глобальные переменные, вы говорите компилятору, чтобы сохранить переменную только для этого файла, и не позволяйте линкеру об этом знать. Поэтому, если вы добавили static (в определении a) к двум примерам кодов, которые я написал, вы не получите столкновений имен просто потому, что компоновщик даже не знает, что есть a в любом из файлы:

a.c:

#include <stdio.h>

static int a;

int compute(void);

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

b.c:

static int a;

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

Это означает, что каждый файл работает со своим a, не зная о других.


В качестве побочного примечания, нормально иметь один из них static, а другой - не до тех пор, пока они находятся в разных файлах. Если два объявления находятся в одном файле (чтение единицы перевода), один static и один extern, см. этот ответ.

Ответ 2

Имя, статичное в каждом файле, не должно вызывать конфликтов имен. Если вы это видите, отправьте (короткий) демонстрационный код, показывающий его, вместе с точным компилятором, который вы используете, чтобы мы могли правильно проверить код и считать его правильным, надлежащим образом очистить компилятор.

Просто FWIW, предпочтительный метод в С++ - это использовать анонимное пространство имен:

namespace { 
    int not_a_static_variable;
}

Честно говоря, я не могу указать на много объективного преимущества для этого, хотя...