VS2015支持魔法静态,为什么会出现此警告?

时间:2016-04-18 13:18:59

标签: c++ visual-studio-2015

我从VS2013升级到VS2015并收到以下警告。我认为VS2015实现了魔法静态,因此本地静态对象应该是线程安全的,那么发生了什么?

C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\system_error(698): error C2220: warning treated as error - no 'object' file generated
  C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\system_error(704): note: see reference to function template instantiation '_Ty &std::_Immortalize<std::_Generic_error_category>(void)' being compiled
          with
          [
              _Ty=std::_Generic_error_category
          ]
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\system_error(698): warning C4640: '_Static': construction of local static object is not thread-safe

错误位于VS安装文件夹的system_error标头中。错误在于此功能:

template<class _Ty> inline
    _Ty& _Immortalize()
    {   // return a reference to an object that will live forever
    static _Immortalizer<_Ty> _Static;
    return (*reinterpret_cast<_Ty *>(&_Static._Storage));
    }

错误中存在的所有上下文,我无法看到system_error实际包含在哪里。

编译器标志是:

/Yu"stdafx.h" /GS /analyze /W3 /wd"4481" /wd"4251" /Zc:wchar_t 
/Zi /Gm- /O2 /sdl /Fd"x64\Release\\Release_vc140.pdb" /Zc:inline /fp:precise
/errorReport:prompt /WX /Zc:forScope /Gd /MT /Fa"x64\Release\" /EHsc /nologo /Fo"x64\Release\" /Fp"x64\Release\MyProj.pch"

更新

对不起,现在好像已修好了。看起来我在v140_xp工具集上并且错误的TargetPlatformVersion。当我以为我将它们全部替换掉​​时,这个必须穿过网。我不太确定为什么这些错误会导致这个错误。无论如何,感谢迄今为止的帮助。

2 个答案:

答案 0 :(得分:2)

看起来它是由伪造的警告引起的,它变成了一个错误,读了这个连接错误:

https://connect.microsoft.com/VisualStudio/feedback/details/2539759/c4640-warning-cannot-be-disabled

错误C2220表示您有启用/ WX开关,它告诉编译器将所有警告视为错误。

您可以使用以下方式关闭此警告:

#pragma warning (disable : 4640) 

<德尔>顺便说一句。不相关,但可能对你有用。您使用_Immortalizer作为类的名称,以下划线开头,后跟大写后缀。标准禁止这样做:请在此处阅读:What are the rules about using an underscore in a C++ identifier?

答案 1 :(得分:2)

这是由MSBuild工具集v140_xp的变化引起的。问题出现在:

  • 使用VS2015 Update 2,工具集v140_xp
  • 构建项目
  • 项目配置为动态库
  • 项目是使用ATL App Wizard创建的,因此* .vcxproj包含标记<Keyword>AtlProj</Keyword>

有解决方法:打开* .vcxproj文件,找到标记<Keyword>AtlProj</Keyword>并将其替换为<Keyword>Win32Proj</Keyword>。编译时不会改变任何内容,但警告将消失。

如果您想了解详情,请导航至C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140\Platforms\Win32\PlatformToolsets\v140_xp目录,打开Toolset.props并找到评论<!-- Added /Zc:threadSafeInit- for ATL dll projects and enable the C4640 warnning -->。它下方的行启用警告并禁用&#34; magic static&#34;来自C ++ 11的功能。

P.S。请注意,警告并不是无用的:&#39; magic static&#39;使用线程本地存储,它遭受丑陋的WindowsXP内核错误:在没有TLS支持的情况下构建应用程序时,从DLL访问TLS会导致崩溃。任何受此错误影响的WinXP支持的DLL插件。