【问题标题】:Strange behaviour when using C++17 static inline members in Visual Studio在 Visual Studio 中使用 C++17 静态内联成员时的奇怪行为
【发布时间】:2018-10-15 04:04:53
【问题描述】:

昨天我问了一个关于这个问题的问题,但我无法给出一个 MVCE。我已经设法用一个简单的程序重现了这一点。问题在于使用 std::list 作为类中的静态内联声明。 Microsoft Visual Studio 确实支持这个新的 C++17 功能。截至 3 月,它有一些错误,但据我所知,它们已经得到修复。以下是如何解决此问题的说明,这发生在调试模式下。

main.cpp

#include <iostream>
#include "header1.h"

int main()
{
    return 0;
}

header1.h:

#include <list>

struct Boo
{
    static inline std::list<int> mylist;
};

另一个CPP.cpp

#include "Header1.h"

当程序退出 main() 时,它会销毁所有静态对象并抛出异常。

如果这没有崩溃,可能是您的系统上的编译器/链接器优化了一些代码,所以您可以尝试让 main.cppanotherCPP.cpp 做某物。在另一个CPP.cpp中:

#include <iostream>
#include "Header1.h"

void aFunction()
{
    std::cout << Boo::mylist.size();
}

并制作 main.cpp:

#include <iostream>
#include "Header1.h"

void aFunction();

int main()
{
    std::cout << Boo::mylist.size();
    afunction();

    return 0;
}

当程序退出时,当 std::list 被清除时,我在这里得到一个异常。这是崩溃的 Visual Studio 调试代码:

for (_Nodeptr _Pnext; _Pnode != this->_Myhead(); _Pnode = _Pnext)
{   // delete an element
    _Pnext = _Pnode->_Next; // Here: Exception thrown: 
                            // read access violation.
                            // _Pnode was 0xFFFFFFFFFFFFFFFF.

    this->_Freenode(_Pnode);
}

仅当我在类中声明静态内联 std::list mylist 时才会发生这种情况。如果我在我的类中将其声明为 static std::list mylist ,然后在一个 .cpp 中将其单独定义为 std::list Boo::mylist; 它工作正常。当我声明 std::list 静态内联并将该类的标头包含在两个 .cpp 文件中时,就会出现此问题。

在我的项目中,我从上面逐步完成了 std::list clear 循环,我记下了“this”指针地址。我逐步完成了循环,因为它释放了我列表中的节点。然后它回来释放其他 std::lists,包括在 std::unordered_map 中(因为他们也使用 std::lists 从它的外观)。最后,当抛出读访问异常并且 _Pnode 是一个无效的指针地址时,我注意到“this”指针地址与清除 std::list 时的“this”指针地址相同 mylist,这让我觉得它试图删除它两次,并且可能是它崩溃的原因。

我希望有人可以重现这个,我不确定这是什么,如果它是一个错误或我做错了什么。这也发生在我的 32 位和 64 位中,但仅限于调试模式,因为我提供的节点释放循环位于宏下:

#if _ITERATOR_DEBUG_LEVEL == 2

【问题讨论】:

  • 看起来这应该是一个 MSVC 错误报告,而不是一个 SO 问题
  • 天真地假设 VS 中的所有错误自 3 月以来都已修复。
  • " 但仅在调试模式下" 我很确定这也发生在发行版中,但它是静默失败。
  • 你应该。在这种特殊情况下,它最多可以与另一个错误报告合并。您似乎很好地掌握了内联变量,无需自我怀疑。

标签: c++ exception inline c++17


【解决方案1】:

此问题已作为错误 here 提交,标题为“在调试模式下对内联静态数据成员进行多次初始化”。

这是在 Visual Studio 2017 版本 15.7 中找到的。

VS 编译器团队已经接受了这一点,并在即将发布的版本中修复了该问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-06
    • 1970-01-01
    • 1970-01-01
    • 2021-04-04
    • 2022-09-17
    • 2013-12-22
    相关资源
    最近更新 更多