Google的C ++风格指南说“我们不使用例外”。该样式在异常使用方面未提及STL。由于STL分配器可能会失败,因此它们如何处理容器引发的异常?
- 如果他们使用STL,如何将分配失败通知呼叫者?STL方法(例如
push_back()
或map)operator[]
不会返回任何状态代码。 - 如果他们不使用STL,则使用什么容器实现?
Google的C ++风格指南说“我们不使用例外”。该样式在异常使用方面未提及STL。由于STL分配器可能会失败,因此它们如何处理容器引发的异常?
push_back()
或map)operator[]
不会返回任何状态代码。Answers:
他们说他们不使用异常,不是没有人应该使用它们。如果您查看基本原理,他们还会写:
由于Google现有的大多数C ++代码都不准备处理异常,因此采用产生异常的新代码相对困难。
通常的遗留问题。:-(
我们根本不至少在应用程序级代码中,处理容器引发的异常。
自2008年以来,我一直是使用C ++的Google搜索工程师。我们确实经常使用STL容器。我个人无法回忆起曾经追溯到诸如vector :: push_back()或map :: operator []之类的单个重大故障或错误,在这里我们说:“噢,我们必须重写此代码,因为分配可能失败”或“当当,如果仅使用异常,则可以避免。” 进程是否耗尽了内存?是的,但这通常是一个简单的错误(例如,有人在程序中添加了一个大的新数据文件,却忘记增加RAM分配)或灾难性故障,无法恢复并继续进行操作。我们的系统已经自动管理并重新启动作业,以使磁盘,宇宙射线等出现故障的机器变得更强大,这确实没有什么不同。
据我所知,这里没有问题。
我敢肯定,他们的意思是他们不使用异常的代码。如果您检查了他们的cpplint脚本,它会检查以确保您包括STL容器的正确标头(例如向量,列表等)。
无论如何,您都无法在现代操作系统上处理分配失败;作为性能优化,它们通常会过量使用内存。例如,如果您malloc()
在Linux上调用并要求一个非常大的内存块,那么即使实际上不存在支持它所需的内存,它也会成功。只有当您访问它时,内核实际上才会尝试分配页面来支持它,这时告诉您分配仍然反而为时已晚。
所以:
除特殊情况外,不要担心分配失败。如果计算机内存不足,那将是灾难性的故障,您无法从中可靠地恢复。
但是,最好的方法是捕获未处理的异常并记录e.what()
输出,然后重新记录throw
,因为这可能比回溯提供更多信息,并且典型的C ++库实现不会自动为您执行此操作。
关于内存不足时如何不能依赖崩溃的上述整个主题很完整,而且很垃圾。C(++)标准可能无法保证,但是在现代系统上,如果内存不足,崩溃是您唯一可以依靠的东西。特别是,您不能依赖于NULL
从分配器获得一个或什至其他任何指示,直到并包括一个C ++异常。
如果您发现自己在可访问页面零的嵌入式系统上,强烈建议您通过在该位置映射一个无法访问的页面来解决此问题。不能依靠人类在NULL
任何地方检查指针,但是您可以通过一次映射页面来解决此问题,而不是尝试纠正某人可能错过了的所有可能的位置(过去,现在和将来)NULL
。
我将通过说出以上条件来限定您使用的是某种自定义分配器,或者您所使用的系统没有过度使用(没有交换的嵌入式系统就是其中的一个例子,但并非唯一)例)。在这种情况下,也许您可以在系统上优雅地处理内存不足的情况。但总的来说,在21世纪,恐怕您不太可能获得这个机会。首先,当事情开始崩溃时,您就会知道系统内存不足。
Stl本身仅在内存分配失败的情况下直接抛出。但是通常,现实世界中的应用程序可能由于多种原因而失败,内存分配失败只是其中之一。在32位系统上,内存分配失败不是可以忽略的事情,因为它可能发生。因此,上面关于内存分配失败将不会发生的整个讨论是没有意义的。即使假设这样做,也必须使用两步初始化来编写一个代码。C ++异常处理在很长一段时间内就已经落后于64位体系结构。我不确定我应该在多大程度上尊敬google在这里显示的负面专业精神,只回答所提出的问题。我记得IBM在1997年前后发表的一篇论文,指出IBM的一些人对C ++异常处理的理解和理解程度。好的专业水平不一定是成功的指标。因此,如果使用STL,放弃异常处理不仅是一个问题。如果有人这样使用C ++,那就是一个问题。这意味着放弃
尽管我没有看到Google的C ++异常处理与Go中的异常处理之间的任何比较,但在这里晚了。具体来说,Go仅通过内置error
类型处理错误。链接的Golang博客帖子明确总结了
正确的错误处理是好的软件的基本要求。通过使用本文中描述的技术,您应该能够编写更可靠和简洁的Go代码。
Golang的创建当然考虑了使用C ++的最佳实践。所述底层的直觉是少可以成多。我没有在Google工作过,但确实发现他们使用C ++和创建Golang可能暗示着该公司的基本最佳实践。