我看到article/%slug%
变量的一些示例在Visual Studio 2017中被初始化(和销毁)了3次。这是链接器的错误吗?还是应该以其他方式发生?
链接器Comdat折叠设置为“关”。
示例代码:
//default us/en/article/%article_name% to article/%article_name%
add_rewrite_rule('^article/([^/]*)?',
'index.php?pagename=$matches[1]&article_locale=us&article_language=en&post_type=article-en',
'top');
在我的解决方案中,我有两次断言触发(一次构造函数称为3次)。 检查调用堆栈显示所有调用堆栈都是相同的,并且所有调用都来自a()的动态初始化程序。现在,我知道一个事实,因为我只是创建该类来研究此问题,所以该类未在解决方案的其他部分使用。
我使用VS17 15.8.9
更新:此处https://developercommunity.visualstudio.com/content/problem/297876/static-inline-variable-gets-destroyed-multiple-tim.html的错误报告(您可以投票以帮助推送错误修正)
答案 0 :(得分:6)
这似乎是MSVC错误。我可以使用下面的代码(也可以使用VS2017 15.8.9)重现它。有趣的是,我只能使用Debug版本进行复制。在发布模式下,优化器似乎可以拯救我们。
Common.h
#pragma once
#include <iostream>
class Foo
{
public:
Foo()
{
std::cout << "Constructing a Foo" << std::endl;
}
~Foo()
{
std::cout << "Destructing a Foo" << std::endl;
}
};
inline Foo const Bar;
other.cpp
#include "common.h"
void DoOtherStuff()
{
std::cout << &Bar << std::endl;
}
main.cpp
#include "common.h"
void DoStuff()
{
std::cout << &Bar << std::endl;
}
extern void DoOtherStuff();
int main()
{
DoStuff();
DoOtherStuff();
}
输出(调试)
Constructing a Foo
Constructing a Foo
00007FF74FD50170
00007FF74FD50170
Destructing a Foo
Destructing a Foo
答案 1 :(得分:4)
我使用MS C ++编译器版本19.16(例如,Visual Studio 15.9.4附带)在调试和发布(/ Ox)模式下均收到该错误。
Inline.Hpp
#include <iostream>
inline struct Foo
{ Foo() { std::cout << "Constructing a Foo at " << this << std::endl; } }
Instance;
Inline.cpp
#include "Inline.Hpp"
int main() { return 0; }
Inline2.cpp
#include "Inline.Hpp"
编译并链接了inline.cpp和inline2.cpp之后,运行时的输出为:
Constructing a Foo at 00BE4028
Constructing a Foo at 00BE4028
编译器和链接器正确地将两个内联定义解析为单个对象,但错误地为每个定义调用了构造函数,而不仅仅是一次。这是一个严重的错误,导致C ++ 17的“内联变量”功能不可用。 “解决方法”是将内联变量视为从19.16版开始仍不受MS C ++支持,即使使用/ std:c ++ 17开关也是如此。
答案 2 :(得分:2)