【问题标题】:c++17: header only: class static variable errorsc++17:仅标头:类静态变量错误
【发布时间】:2018-03-30 05:43:28
【问题描述】:

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

ma​​in.cpp

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

foo.cpp

#include "foo.h"

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

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

如您所见,它在同一个位置被构造了两次并被破坏了两次 - 不好。

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

还有其他方法可以仅在标题中获取类静态信息吗?这在 C++17 中是否发生了变化?

【问题讨论】:

  • 我没有看到 clanggcc 上的行为。不过,还没有测试过 MSVC。可能是 MSVC 错误,但在提交之前,请务必检查预览版本
  • 主要功能是什么?

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


【解决方案1】:

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

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

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

希望这个内联时的静态变量错误将很快在他们的下一个补丁中得到修复。

同时,我发现在Release Mode 中编译会使您的reporter 按预期仅初始化一次,而在Debug Mode 中,此错误发生在他们的后端优化 .

所以我猜这至少不会出现在你的产品中。

【讨论】:

【解决方案2】:

这是 MSVC 中的一个错误。

静态类成员thingy::rep,如thingy,有external linkageinline 说明符不会改变这一点。

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

[class.static.data]/5:

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

【讨论】:

    猜你喜欢
    • 2021-04-04
    • 1970-01-01
    • 1970-01-01
    • 2018-12-10
    • 2011-08-27
    • 2015-01-20
    • 1970-01-01
    • 2017-12-24
    • 2018-07-31
    相关资源
    最近更新 更多