c++ 17:仅 header :类静态变量错误

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

自 C++17 以来,我一直在试验更简单的方法来获取类静态变量。我正在写一个只有标题的库。显然,变量的 inline 的新含义适用于此。

class thingy {
    static inline reporter rep;
};

但我一直遇到运行时错误。

我正在使用 Visual Studio 15.6.4

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

  • thingy 有一个静态成员变量
  • 成员告诉你它什么时候构造/销毁以及在什么地址
  • 应该恰好构造和销毁一次
  • #included 在两个.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 中有变化吗?

最佳答案

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

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

This will be addressed in 15.7 - thanks for the report! Combining multiple guards for adjacent static variables into a single guard is a backend optimization which can go wrong when inlining under certain circumstances. That's basically the issue here.

希望这个内联时的静态变量 bug 将在他们的下一个补丁中尽快修复。

与此同时,我发现在 Release Mode 下编译会让你的 reporter 按预期初始化一次,而在 Debug Mode 这个错误发生在他们的后端优化

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

关于c++ 17:仅 header :类静态变量错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49569026/

相关文章:

visual-studio - 如何在 Visual Studio 2010 中从 C++ 源代码生成汇编代码

c++ - 模板内嵌套类型名称的流运算符重载

parallel-processing - 编译器通常会在没有明确告知的情况下发出向量 (SIMD) 指令吗?

c++ - 关于类成员指针的一些问题

c++ - 为什么虚拟基类必须由最派生的类来构造?

c++ - 从文件中读取单个字符返回特殊字符?

mysql - 使用 OCI、MySQL 和 LabView 构建 DLL 一直失败

c - 如何在 MSVC 中访问 libsndfile-1.dll 中的函数?

c++ - 根据实例数自动设置ID

c++ - "const T &arg"与 "T arg"