静态内联函数与静态变量

时间:2016-01-21 15:15:40

标签: c++ c++11

阅读static variables in an inlined function后,我写了这个测试程序:

main.cpp中:

#include <iostream>
#include "a.h"
#include "f.h"

void g();

int main()
{
    std::cout << "int main()\n";
    f().info();
    g();
}

A.H:

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;
}
}

g.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中的错误吗?程序的行为是否未定义?如果我替换&#34;命名空间{...}&#34;用&#34;静态&#34;在f.h中,按照预期在g()内部调用A :: A()。这种行为不应该是一样的吗?

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

1 个答案:

答案 0 :(得分:3)

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

似乎icpc不遵循C ++ 11标准,而是遵循C ++ 03,它允许使用外部链接声明这些名称。因为当你使用f() icpc明确地使static内部跟随诉讼时,我强烈怀疑这只是一个错误。