首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MSVC 2010编译的应用程序和MSVC 2019编译的应用程序之间的行为差异

MSVC 2010编译的应用程序和MSVC 2019编译的应用程序之间的行为差异
EN

Stack Overflow用户
提问于 2020-05-21 14:27:41
回答 1查看 48关注 0票数 0

我正在开发一个MFC应用程序。我们最近将应用程序从使用MSVC2010编译器(v100工具集)迁移到使用MSVC2019编译器(v142工具集)。在升级到MSVC 2019之后,我们看到应用程序的行为有一个不同之处。

在使用MSVC2010编译器(v100工具集)编译的应用程序中,当应用程序的主窗口关闭时,应用程序通过调用主机窗口类的OnClose()函数来启动退出进程。在销毁序列中,我们在其中一个类的析构函数中有日志记录代码,该代码实际上终止了对悬空指针的引用(该指针指向日志记录类的一个实例,而导致访问冲突的行正试图调用这个日志记录类实例上的函数,该实例已经在前面被销毁了)。当这种访问冲突发生时,我可以在Visual Studio2010输出窗口中看到消息"First-chance exception at in the :0xC0000005:Access violation at location“。我们在这个特定的调用层次结构中没有任何catch块来捕获这个访问冲突异常,因此我们期望应用程序终止。在按下F10 (看看是否可以移动到下一行)之后,此时显示的调用堆栈如下所示:

exe_name!’class_name::function_name’::’1’::catch$0()线路line_no

Msvcr100.dll!_CallSettingFrame()第44行

Msvcr100.dll!_CxxCallCatchBlock(_EXCEPTION_RECORD * pExcept) 1337行

当我调试并按下F10时,我能够跳过导致访问冲突的那一行。看起来运行时似乎正在抑制异常(或以某种方式捕获它),因为我能够越过导致访问冲突的行。有没有人能解释一下,为什么在出现未处理的异常后,应用程序仍在继续。

在VC10和VC19的exe项目属性中,我们为“C/ C++ ->代码生成和启用C++异常”选择了编译器选项“Yes with SEH Exceptions (/EHa)”。

在使用MSVC2019编译器(v142工具集)编译的应用程序中,完全相同的代码行导致运行时检测到纯虚拟函数调用,应用程序崩溃。我想要了解的正是这种行为上的差异( MSVC 2010编译的应用程序和MSVC 2019编译的应用程序之间)。

我知道取消引用悬空指针会导致未定义的行为。但是,我不能理解在VC 2010编译的应用程序中,我如何能够调试(或继续)通过导致访问冲突异常(尚未处理)的行。

EN

回答 1

Stack Overflow用户

发布于 2020-05-21 14:48:29

欢迎来到未定义行为的奇怪世界,在这里literally anything can happen (好的,也许什么都不是,但可能会发生很多不好的事情)。

我知道取消引用悬空指针会导致未定义的行为。但是,我不能理解在VC 2010编译的应用程序中,我如何能够调试(或继续)通过导致访问冲突异常(尚未处理)的行。

关键是它没有任何解释。或者更确切地说,它是未定义的行为本身就是解释。一旦你在你的程序中有了未定义的行为,所有的赌注都会失效。它可以很好地工作,只是越过了线。另一方面,它可能会崩溃。你永远不会真正知道你会得到哪一个。

这就是为什么你不应该在你的程序中有未定义的行为。您不能保证它在每个实现上都有效,甚至有时在相同的实现上也是如此。有时,编译器会选择以不同的方式进行优化,从而导致之前运行的代码崩溃。所以它通常是最好避免的。

至于为什么在这种情况下这样做,微软很可能已经以一种不利的方式改变了他们的实现,从而影响了你在不崩溃的情况下做到这一点的能力。但具体是什么,我不能告诉你。如果不知道微软在他们的实现中做了什么,以及你在代码中做了什么的具体例子,我就无法真正知道。

我的建议是,既然你似乎已经知道错误是从哪里来的,那就简单地找到一种方法,确保在指针被销毁后,你不会尊重它。这样,无论您使用哪种编译器,您都可以确保它能够正常工作。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61928563

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档