c++ - 静态成员函数,名称相同,代码不同,只使用第一个遇到的版本,这是为什么?

标签 c++ linker static-members

我偶然发现了这种奇怪的行为(在我试图证明如果在头文件中定义了 instance() 函数,Scott Meyers 单例模式将为每个 .cpp 文件生成不同的单例实例之后,但没关系)。

它产生什么:

代码生成此输出 - 0 2 4 60 1 2 3 取决于编译顺序(无论是 test1. cpp 或 test2.cpp 已先编译)。

我的期望:

我期望结果为 0 0 1 2,因为这 2 个函数应该对 2 个单独的静态变量进行操作,即使它们具有相同的名称,更不用说 Foo::foo() 在每个编译单元中是不同的函数。

但似乎 test1()test2() 调用了 Foo::foo() 的版本第一次在编译时遇到,这让我很惊讶。

这是代码:

test1.cpp

static int var = 0;
class Foo {
public:
    static void foo() {
        printf("%d ", var);
        var += 2;             // <--- This is the difference!
    }
};
void test1() {
    Foo::foo();
}

test2.cpp

static int var = 0;
class Foo {
public:
    static void foo() {
        printf("%d ", var);
        var++;                // <--- This is the difference!
    }
};
void test2() {
    Foo::foo();
}

main.cpp

void test1();
void test2();
int main() {
    test2();
    test1();
    test2();
    test1();
    return 0;
}

我的问题

我想,我的问题是,为什么编译器会这样做,它是由标准指定的吗?标准对于在不同的编译单元中具有不同的类实现有何规定,前提是它们仅在那个编译单元?

最佳答案

您违反了“一个定义规则”(第 3.2 节):

Given such an entity named D defined in more than one translation unit, then

  • each definition of D shall consist of the same sequence of tokens; and
  • in each definition of D, corresponding names, looked up according to 3.4 , shall refer to an entity defined within the definition of D, or shall refer to the same entity, after overload resolution (13.3) and after matching of partial template specialization (14.8.3), except that a name can refer to a const object with internal or no linkage if the object has the same literal type in all definitions of D, and the object is initialized with a constant expression (5.19), and the value (but not the address) of the object is used, and the object has the same value in all definitions of D; and
  • in each definition of D, corresponding entities shall have the same language linkage; and
  • in each definition of D, the overloaded operators referred to, the implicit calls to conversion functions, constructors, operator new functions and operator delete functions, shall refer to the same function, or to a function defined within the definition of D; and
  • ...

If the definitions of D satisfy all these requirements, then the program shall behave as if there were a single definition of D.

If the definitions of D do not satisfy these requirements, then the behavior is undefined.

因此,两个文件中的 Foo::foo() 应该是相同的方法。 否则,行为是未定义的。

关于c++ - 静态成员函数,名称相同,代码不同,只使用第一个遇到的版本,这是为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32504059/

相关文章:

c++ - Cocos2dx、box2d坦克

c++ - LNK2019在visual studio中无法链接静态库

c++ - 如何在交叉编译期间强制链接到未安装的库

gcc - 动态链接的 glibc 应用程序 dlopen() 可以是静态链接的 musl 共享对象吗?

c++ - 结构/类中静态常量的奇怪 undefined symbol

c++ - 交叉编译 Ubuntu 到 Beaglebone 后无法在目标上找到共享库

c++ - 静态库中的静态变量与动态 dll

c++ - 类中静态变量的地址

Android 静态对象生命周期

c++ - std::min_element 编译错误