Это небезопасно, потому что у вас есть две структуры с именем S
.Ключевое слово static
применяется только к объявлению переменной;это эквивалентно тому, что вы написали:
struct S {
int Value() {return 1;}
};
static S s1;
Компилятор не замечает этого во время компиляции, поскольку имеет дело с каждой единицей перевода отдельно.Функции Value
в структурах имеют одно и то же имя и становятся слабыми глобальными символами в объектных файлах, поэтому компоновщик не выдает ошибку о конфликте имен символов;он просто выбирает один для использования в полностью связанном двоичном файле.Вероятно, это будет первое определение символа, что означает, что вы на самом деле можете получить различное поведение в зависимости от порядка, в котором вы связали объекты:
> g++ -o test test.o test1.o test2.o && ./test
s1 is 1
s2 is 1
> g++ -o test test.o test2.o test1.o && ./test
s1 is 2
s2 is 2
Вы можете обойти это, обернув структуры в анонимныйпространства имен (которые сделают функциональные символы Value
локальными вместо слабых глобальных):
namespace {
struct S {
int Value() {return 1;}
} s1;
}
Или просто удалив имя структуры, поскольку оно вам на самом деле не нужно:
struct {
int Value() {return 1;}
} s1;