简体   繁体   English

VS2015 C ++静态初始化崩溃,可能是错误

[英]VS2015 C++ static initialization crash, possible bug

I'm seeing something weird happening with Visual Studio 2015 Community. 我看到Visual Studio 2015社区发生了一些奇怪的事情。 Code that worked perfectly in VS2012 crashes at startup when ported to VS2015, before main is invoked: the classic symptoms of some static initialization mess. 在调用main之前,移植到VS2015时,在VS2012中完美工作的代码在启动时会崩溃:一些静态初始化混乱的经典症状。 I have a few static variables, but used properly, with the standard "Construct On First Use" pattern, eg: 我有一些静态变量,但使用正确的标准标准“首次使用时构造”模式,例如:

const int& i()
{
  static int *v = new int(1);
  return *v;
}

The code above causes an assert from the runtime while initializing the program (see image http://i.stack.imgur.com/nsQGS.png ). 上面的代码在初始化程序时导致运行时断言(请参见图像http://i.stack.imgur.com/nsQGS.png )。 Pressing retry simply quits the program: no call stack, no information whatsoever. 按重试只是退出程序:没有调用堆栈,没有任何信息。

The code below however works flawlessly: 但是,以下代码可以完美地工作:

const int& i()
{
  static int *v = nullptr;
  if (v == nullptr)
    v = new int(1);
  return *v;
}

It seems to me that VS2015 is doing what looks like some (illegal) optimization (even in a debug build), by executing the static variable initialization code during program initialization, and not the first time that the function is called, as the C++ standard requires. 在我看来,VS2015通过在程序初始化期间(而不是作为C ++标准首次调用该函数)执行静态变量初始化代码来进行某种(非法)优化(即使在调试版本中)需要。 I tried several variations of the code above: class methods, free functions, different objects (std::vector, cv::Mat), always with the same result: the static pointer has to be initialized to null or the program doesn't start. 我尝试了上面代码的几种变体:类方法,自由函数,不同的对象(std :: vector,cv :: Mat),总是得到相同的结果:静态指针必须初始化为null或程序不需要开始。

So... am I missing something or is VS2015 actually messing up badly? 所以...我错过了什么还是VS2015真的搞砸了吗?

UPDATE: 更新:

I spent some time trying to find the minimal setup that shows the problem, and this is what I got: 我花了一些时间试图找到显示问题的最小设置,这就是我得到的:

  1. create a project using the "CLR empty project" template. 使用“ CLR空项目”模板创建一个项目。
  2. add a cpp file, containing just the offending function and main(). 添加一个cpp文件,其中仅包含有问题的函数和main()。 Main can be empty, it doesn't matter: the bug occurs BEFORE it is even reached. Main可以为空,没关系:该错误在到达之前就已发生。
  3. add 'main' as entry point (or you get a link error). 添加“ main”作为入口点(否则会出现链接错误)。

The x86 version works, but the x64 doesn't. x86版本有效,但x64版本无效。

For comparison, a project with the identical code but created as "Win32 console application" doesn't have the problem, even after adding the /CLR option. 为了进行比较,即使添加/ CLR选项,具有相同代码但创建为“ Win32控制台应用程序”的项目也没有问题。 I can see differences in the vcxproj files, but none justifies the error, although one or more of them clearly IS the cause. 我可以看到vcxproj文件中的差异,但是没有一个可以证明错误,尽管其中一个或多个显然是原因。

Is there a way to upload a zip with the project? 有没有办法上传项目的zip文件?

Well, @bogdan got it right. 好吧,@ bogdan正确了。 My project had a mix of settings that was neither /SUBSYSTEM:CONSOLE nor /SUBSYSTEM:WINDOWS. 我的项目混合了既不是/ SUBSYSTEM:CONSOLE也不是/ SUBSYSTEM:WINDOWS的设置。 Once I fixed that, everything started to work as expected. 一旦我解决了这个问题,一切就会开始按预期进行。 My test projects had the same problem, I blame Microsoft for not having a clear "CLR windows app" C++ template any more in VS2015 (they want to push you to use C# for that, which makes sense most of the times, but not always). 我的测试项目也遇到了同样的问题,我怪微软在VS2015中没有清晰的“ CLR Windows应用” C ++模板(他们想让您为此使用C#,这在大多数情况下是有意义的,但并非总是如此) )。

I found this page particularly useful in explaining all the different settings that have to be consistent (it's not just /SUBSYSTEM...). 我发现此页面在解释必须一致的所有不同设置时特别有用(不仅仅是/ SUBSYSTEM ...)。

I wish I could mark @bogdan's comment as answer, but I can't see anything to do that. 我希望我可以将@bogdan的评论标记为答案,但是我看不到有什么可以做的。

Thanks Bogdan! 谢谢波格丹!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM