h文件中的静态关键字和内部链接

时间:2010-11-25 11:58:16

标签: c++ static linkage one-definition-rule

另一个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被声明{{1它有内部链接,编译器很高兴。 由于static也被声明为静态,它也有内部链接,我希望它的值不会在两个counter文件中共享 - 但程序输出意味着值是共享的,因为它最多可达2个。

任何见解?

编辑: 关于在cpph文件中声明静态变量的上下文中被认为是“良好的编程习惯”的任何答案也受到欢迎。

1 个答案:

答案 0 :(得分:11)

如果差异源文件之间共享StaticTest.h,那么您将获得未定义的行为。

如果您在不同的翻译单元中定义类或内联函数,那么它们的定义必须相同(相同的标记序列),并且至关重要的是,任何标识符必须引用相同的实体(除非const对象具有内部联系),如另一个翻译单位的定义。

您违反此规定是因为counter具有内部链接,因此在不同的翻译单元中,函数定义中的标识符指的是不同的对象。

参考:C ++ 03 3.2 [basic.def.odr] / 5.