具有静态变量的静态内联函数

static inlined function with static variables

本文关键字:静态 函数 变量      更新时间:2023-10-16

在内联函数中读取静态变量后,我编写了这个测试程序:

主.cpp:

#include <iostream>
#include "a.h"
#include "f.h"
void g();
int main()
{
    std::cout << "int main()n";
    f().info();
    g();
}

啊:

struct A
{
    A() { std::cout << "A::A()n"; }
    void info() { std::cout << this << 'n'; }
};

f.h:(由于命名空间未命名,每个编译单元的本地单例)

namespace {
inline A& f()
{
    static A x;
    return x;
}
}

克.cpp:

#include <iostream>
#include "a.h"
#include "f.h"
void g()
{
    std::cout << "void g()n";
    f().info();
}

问题是我使用不同的编译器没有得到相同的结果:

g++ 4.8.2:确定

int main()
A::A()
0x6014e8
void g()
A::A()
0x6014d0

clang++ 3.7.0:确定

int main()
A::A()
0x6015d1
void g()
A::A()
0x6015c1

ICPC 15.0.2:在 g() 中不调用 A::A() !

int main()
A::A()
0x601624
void g()
0x601620

这是 icpc 中的错误吗?程序的行为没有定义吗?如果我在 f.h 中将"命名空间 {...}"替换为"静态",则按预期在 g() 中调用 A::A()。行为不应该是一样的吗?

如果我在 f.h 中删除"命名空间 {...}",A::info() 会在 main() 和 g() 中打印相同的对象地址,并且 A::A() 只按预期调用一次(使用所有编译器)。

由于 C++11 要求未命名命名空间中的名称具有内部链接,因此每个翻译单元都应该有自己的f()版本,因此,它是自己的static A x版本。所以 gcc 和 clang 是正确的。

似乎 icpc 没有遵循 C++11 标准,而是遵循 C++03,这允许通过外部链接声明这些名称。因为当您使用 icpc 明确地将f()内部static效仿时,我强烈怀疑这只是一个错误。