【问题标题】:static inlined function with static variables带有静态变量的静态内联函数
【发布时间】:2016-04-27 21:59:48
【问题描述】:

看完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();
}

啊哈:

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

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

【问题讨论】:

  • 可能相关:stackoverflow.com/questions/8784892/…。你不能真的说,你没有得到构造函数调用,只是输出没有发生。而且由于您在静态构造函数国家/地区,因此您可能会遇到另一个错误。
  • 程序已被所有编译器使用“-std=c++11”编译。
  • 您的源代码和程序输出不匹配。 main() 输出 "void g()\n".
  • @Arne 谢谢,已更正

标签: c++ c++11


【解决方案1】:

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

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

【讨论】:

  • 程序已被所有编译器使用“-std=c++11”编译。
  • @Jac 这并不能防止编译器出现错误。
  • 如果它是外部链接的,在一个内存位置不会有一个对象吗? icpc 运行返回两个不同的内存位置。好像你只是没有在构造函数调用中得到输出......
  • 否:每个编译单元(g.cpp 和 main.cpp)应该有(并且有)1 个对象,因为 f() 在未命名的命名空间中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-16
  • 1970-01-01
  • 2017-09-02
  • 2016-08-30
  • 2023-03-18
  • 2013-11-04
  • 1970-01-01
相关资源
最近更新 更多