gpt4 book ai didi

c++ - 为什么动态检查C++0x的 `noexcept`?

转载 作者:太空宇宙 更新时间:2023-11-04 13:43:59 25 4
gpt4 key购买 nike

我很好奇 C++0x FCDnoexcept 背后的基本原理. throw(X) 已被弃用,但 noexcept 似乎做同样的事情。在编译时不检查 noexcept 是否有原因?如果静态检查这些函数,它们只在 try block 中调用抛出函数,似乎会更好。

最佳答案

基本上,这是一个链接器问题,标准委员会不愿意破坏ABI。 (如果由我来决定,我会这样做,它真正需要的只是重新编译库,我们已经在启用线程的情况下遇到了这种情况,并且它是可管理的。)

考虑一下结果如何。假设需求是

  1. 每个析构函数都是隐式的noexcept(true)
    • 可以说,这应该是一个严格的要求。抛出析构函数总是一个错误。
  2. 每个 extern "C"都是隐式的 noexcept(true)
    • 同样的论点:C 区的异常总是是一个错误。
  3. 除非另有说明,否则所有其他函数都是隐式noexcept(false)
  4. noexcept(true) 函数必须将其所有 noexcept(false) 调用包装在 try{}catch(...){}
    • 以此类推,const方法不能调用非const方法。
  5. 此属性必须在重载解析、函数指针兼容性等方面表现为不同的类型。

听起来很合理,对吧?

要实现这一点,链接器需要区分函数的 noexcept(true)noexcept(false) 版本,就像您可以重载 const 和 const 版本一样成员函数。

那么这对名称窃取意味着什么?为了与现有目标代码向后兼容,我们需要将所有现有名称解释为 noexcept(false),并对 noexcept(true) 版本进行额外的处理。

这意味着我们不能链接现有的析构函数,除非修改 header 以将它们标记为 noexcept(false)

  • 这会破坏向后兼容性,
  • 这可以说是不可能的,见第 1 点。

我亲自与一位标准委员会成员谈过这个,他说这是一个仓促的决定,主要是由于容器中移动操作的限制(否则你可能会在一次抛出后丢失元素,这违反了基本保障)。请注意,这个人的设计理念是容错代码是好的。得出自己的结论。

就像我说的,我宁愿破坏 ABI 而不是破坏语言。 noexcept 只是对旧方法的边际改进。静态检查总是更好。

关于c++ - 为什么动态检查C++0x的 `noexcept`?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26658678/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com