为什么Qt没有使用异常处理?

70

我一直很好奇,因为Qt几乎使用了标准C++中的每个特性并以出色而创新的方式进行了使用;当它没有使用某个特定特性时,它有一个完美有效且适用的理由。在这种情况下,为什么没有Qt类使用throw关键字或抛出任何异常?他们不要求在我们编写的Qt代码中需要try ... catch块的理由是什么?

个人而言,我自己并不太喜欢它,无论我是否正在使用Qt,我总是选择使用错误代码和返回值而不是抛出异常对象。但为什么我在他们的文档中没有看到QException类?Qt开发者对此持有什么观点?


3
另外需要注意的是,大多数情况下 new 可能会抛出 std::bad_alloc 异常,因此如果您想编写健壮的代码,请不要过于放心。 - odinthenerd
3个回答

70
出于历史原因,大多数情况下是这样。编译器中的异常支持需要相当长的时间才能成熟。引用 Nokia 的Tobias Hunger所说:
“当 Qt 开始时,并不是所有需要支持 Qt 的编译器都支持异常。今天我们试图保持 API 的一致性,因此通常不会向没有使用异常的模块添加新代码使用异常。您会注意到 Qt 的一些新模块使用了异常。”
我认为这基本上概括了它。

4
我猜现在是适应新时代的时候了。历史原因不能阻止我们使用这样一个好功能。 - Raúl Salinas-Monteagudo
4
来自Qt官方文档的一个理由:Qt本身不会抛出异常,而是使用错误码。此外,一些类具有用户可见的错误消息,例如QIODevice :: errorString()或QSqlQuery :: lastError()。这是历史和实际原因 - 启用异常会使库大小增加超过20%。 - patryk.beza

13
如果你在谷歌上搜索“qt异常”,你会得到很多关于这个话题的讨论。这里有一个“官方”的答案:
当Qt起初开发时,不是所有需要支持的编译器都支持异常。今天我们试图保持API的一致性,所以那些从来没有使用过异常的模块通常不会添加新的代码来使用异常。
你会注意到在一些新的Qt模块中使用了异常。
如果你在助理索引中查找异常(即在Qt文档中),你会找到一些异常类,例如QtConcurrent :: Exception。

7
您可以在KDE开发邮件列表的这里阅读一个关于异常的很好、大部分文明的辩论。由于KDE和QT有关,我认为相同的问题适用,这些问题(如果我正确地阅读了线程)可概括如下:
  • 根据编译器,异常存在性能问题。
  • 通过不从库中抛出异常来保护库的用户免于使用异常的义务。
  • C++异常规范方面的问题。

2
什么性能问题?Bjarne在他的新书中似乎写道,如果它们不发生,那么它几乎是无操作,如果发生了,那么最多只是一个函数调用开销?此外,规范中有什么问题?我没有理解屏蔽部分。你能详细说明一下吗? - László Papp
嗨@LaszloPapp,如果您阅读我提供的线程链接,我的观点大多会变得清晰明了。否则,我认为两个评分较高的答案可能比我的更准确。 - jilles de wit
1
@Ipapp:Bjarne并不知道所有的实现问题...几年前,MinGW(GCC的Windows端口)启用异常后性能大幅下降(25%),即使代码中没有使用它们。现在这个问题基本上已经解决了,但很明显异常在一段时间内一直是一个问题,即使主流编译器(Linux下的gcc、msvc等)没有问题。 - galinette
回复:屏蔽。我理解这意味着Qt的用户可以放心,Qt代码不会抛出任何异常,因此无需确保自己的代码能捕获任何(意外的)异常。所以少了一件需要担心的事情。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接