我发现 Visual Studio 2015 Community 发生了一些奇怪的事情。在 VS2012 中完美运行的代码在移植到 VS2015 时会在调用 main 之前在启动时崩溃:一些静态初始化混乱的典型症状。我有一些静态变量,但使用标准的“首次使用时构造”模式正确使用,例如:
const int& i()
{
static int *v = new int(1);
return *v;
}
上面的代码在初始化程序时会导致运行时发出断言(参见图片https://i.stack.imgur.com/nsQGS.png)。按重试只是退出程序:没有调用堆栈,没有任何信息。
然而,下面的代码可以完美地工作:
const int& i()
{
static int *v = nullptr;
if (v == nullptr)
v = new int(1);
return *v;
}
在我看来,VS2015 正在做一些看起来像一些(非法)优化的事情(即使是在调试版本中),通过在程序初始化期间执行静态变量初始化代码,而不是第一次调用该函数,就像 C++ 标准一样需要。
我尝试了上面代码的几种变体:类方法、自由函数、不同的对象(std::vector、cv::Mat),总是得到相同的结果:静态指针必须初始化为 null,否则程序不会开始。
那么...我错过了什么还是 VS2015 实际上搞砸了?
UPDATE:
我花了一些时间试图找到显示问题的最小设置,这就是我得到的:
- 使用“CLR 空项目”模板创建一个项目。
- 添加一个 cpp 文件,仅包含有问题的函数和 main()。 Main 可以为空,但这并不重要:错误发生在到达之前。
- 添加“main”作为入口点(否则您会收到链接错误)。
x86 版本可以工作,但 x64 则不行。
为了进行比较,即使添加了 /CLR 选项,具有相同代码但创建为“Win32 控制台应用程序”的项目也不会出现问题。我可以看到 vcxproj 文件中的差异,但没有一个可以证明该错误是合理的,尽管其中一个或多个显然是原因。
有没有办法上传项目的 zip 文件?
嗯,@bogdan 说得对。我的项目混合了既不是 /SUBSYSTEM:CONSOLE 也不是 /SUBSYSTEM:WINDOWS 的设置。一旦我解决了这个问题,一切就开始按预期进行。我的测试项目也有同样的问题,我责怪微软在 VS2015 中不再有一个清晰的“CLR windows 应用程序”C++ 模板(他们想促使你使用 C#,这在大多数情况下都是有意义的,但并不总是如此) )。
I found 这一页在解释必须保持一致的所有不同设置时特别有用(不仅仅是 /SUBSYSTEM...)。
我希望我可以将 @bogdan 的评论标记为答案,但我看不到任何可以做到这一点的东西。
谢谢博格丹!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)