c ++ 17:仅限标题:类静态变量错误

时间:2018-03-30 05:43:28

标签: c++ visual-c++ c++17 static-variables

从C ++ 17开始,我一直在尝试更简单的方法来获取类静态变量。我正在编写一个仅限标题的库。显然inline对变量的新含义适用于此。

class thingy {
    static inline reporter rep;
};

但我一直在收到运行时错误。

我正在使用Visual Studio 15.6.4

要测试,请执行以下操作:

  • thingy有一个静态成员变量
  • 会员告诉您何时构建/破坏以及在何处使用
  • 应该构造和破坏一次
  • #include包含在两个.cpp文件中

foo.h中

#pragma once

#include <iostream>

using namespace std;

struct reporter {
    reporter() {
        cout << "reporter() - " << this << endl;
    }
    ~reporter() {
        cout << "~reporter() - " << this << endl;
    }
};

class thingy {
    static inline reporter rep;
};

的main.cpp

#include "foo.h"
int main() {}

Foo.cpp中

#include "foo.h"

最令人失望的是,它打印出来:

reporter() - 00007FF670E47C80
reporter() - 00007FF670E47C80
~reporter() - 00007FF670E47C80
~reporter() - 00007FF670E47C80

正如你所看到的,它被构造了两次并且在同一个位置被破坏了两次 - 不太好。

我是否误解了inline变量的用途?

是否有另一种方法只能在标题中获取类静态?这在C ++ 17中发生了变化吗?

2 个答案:

答案 0 :(得分:6)

它看起来像VS2017中的一个错误。

可以找到一些相关的错误报告,但它们并不完全符合您的情况:

  

这将在15.7中解决 - 感谢您的报告!   将相邻静态变量的多个保护组合成单个保护是后端优化,在某些情况下内联时可能会出错。这基本上就是问题所在。

希望在内联编辑错误时,这个静态变量很快就会在下一个补丁中修复。

与此同时,我发现在Release Mode中进行编译会使reporter初始化只按预期,而在Debug Mode中,会出现后端优化

所以我想这至少不会进入你的产品。

答案 1 :(得分:0)

这是MSVC中的一个错误。

静态类成员thingy::repthingy一样external linkageinline说明符不会改变它。

因此,整个程序中只能有one个实例,因此只能初始化一次。

[class.static.data]/5

  

命名空间范围内的类的静态数据成员具有该类的链接。