статическое ключевое слово в файле h и внутренняя связь - PullRequest
14 голосов
/ 25 ноября 2010

Еще один static вопрос. Я прочитал следующее:

И я до сих пор не могу понять следующее поведение: У меня есть один h файл:

// StaticTest.h
#include <stdio.h>

static int counter = 0;

struct A {
    A () {
        counter++;
        printf("In A's ctor(%d)\n", counter);
    }
    ~A () {
        counter--;
        printf("In A's dtor(%d)\n", counter);
    }
};

static A a;

и два cpp файла:

// StaticTest1.cpp
#include "StaticTest.h"

int main () {
 return 0;
}

И

// StaticTest2.cpp
#include "StaticTest.h"

Вывод программы:

In A's ctor(1)
In A's ctor(2)
In A's dtor(1)
In A's dtor(0)

Теперь конструктор A вызывается дважды, поскольку файл h включается дважды, а поскольку экземпляр A с именем a объявлен static, он имеет внутреннюю связь и компилятор счастлив. Так как counter также объявлен как статический, он также имеет внутреннюю связь, и я ожидаю, что его значение не будет совместно использоваться в двух cpp файлах --- но вывод программы подразумевает, что значение является общим, так как оно считается до 2.

какие-либо идеи?

EDIT: Любые ответы относительно того, что считается «хорошей привычкой программирования» в контексте объявления статических переменных в файлах h против cpp, также приветствуются.

1 Ответ

11 голосов
/ 25 ноября 2010

Если StaticTest.h является общим для исходных файлов различий, то вы получите неопределенное поведение.

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

Вы нарушаете это, потому что counter имеет внутреннюю связь, поэтомув разных единицах перевода идентификатор в определениях функций относится к другому объекту.

Ссылка: C ++ 03 3.2 [basic.def.odr] / 5.

...