我对C/C++不了解的是:
是的,每个人都使用它来获得超快速的可执行文件,因此它们会在启用优化的情况下进行编译.
但是对于打开调试信息的编译,我们并不关心速度.那么为什么不在该编译模式中包含更多信息,例如在它们发生之前检测一些段错误?实际上,assert(ptr != NULL)
在每次访问指针之前插入一个ptr
.为什么编译器不能这样做?同样,默认情况下应该关闭,但我认为应该有这种可能性.
编辑:有些人说,我建议的检测没有意义或没有做任何报告segmentation fault
不会做的事情.但我想到的只是一个更优雅和信息丰富的中止,它打印出违规代码的文件名和行号,就像一样assert()
.
在这种情况下,该计划应该做些什么?如果它通知用户一个错误,那就是segfault的作用.
如果它应该继续下去并避免错误,它怎么知道该怎么办?
更不用说如果它以某种方式神奇地知道如何继续正确,那么你的发布版本中就有一个错误(调试版本旨在帮助你识别和修复错误 - 而不是隐藏它们).
回应问题中添加的其他信息(我想我误解了你的意图):
我想到的只是一个更优雅和信息丰富的中止,它打印出违规代码的文件名和行号,就像assert()一样.
这是编译器可以做的事情 - 正如你所说,编译器本质上会自动插入assert()
指针被解除引用的任何地方.这可能会大大增加调试版本的大小,但对于许多(或大多数)目的而言,它可能仍然可以接受.我认为这对于编译器来说是一个合理的选择.
我不确定编译器供应商会说什么......也许在微软的Connect网站上发布VC++产品的请求,看看他们说了什么.
您的建议存在一些主要问题:
您希望编译器检测什么条件?在Linux/x86上,未对齐访问可能导致SIGBUS
并且堆栈溢出可能导致SIGSEGV
,但在这两种情况下,技术上都可以编写应用程序来检测这些条件并"正常"失败. NULL
可以检测到指针检查,但最隐蔽的错误是由于无效的指针访问,而不是NULL
指针.
C和C++编程语言提供了足够的灵活性,因此如果给定的随机地址是任意类型的有效指针,则运行时无法100%成功确定.
在检测到这种情况时,您希望运行时环境做什么?它无法纠正行为(除非你相信魔法).它只能继续执行或退出.但是等一下......这就是信号传递时已经发生的事情!程序退出,生成核心转储,应用程序开发人员可以使用该核心转储来确定程序崩溃时的状态.
你提倡的实际上听起来像你想在调试器(gdb
或)通过某种形式的虚拟化(valgrind
)运行你的应用程序.这已经成为可能,但默认情况下这样做是没有意义的,因为它对非开发人员没有任何好处.
更新以回复评论:
没有理由修改调试版本的编译过程.如果您需要应用程序的"温和"调试版本,则应在调试器内部运行它.将您的可执行文件包装在一个透明地为您执行此操作的脚本中非常容易.