问题标签 [noexcept]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - 添加 `noexcept(false)` 是否对代码有任何好处?
最近在我的代码中,我一直在明确编写noexcept(false)
我知道会引发异常的函数,主要是为了阅读代码的人。但是,我想知道这是否会影响我的代码的行为或编译器解释它的方式。它有什么不同吗?
注意:我知道析构函数是隐含的 noexcept 并且您必须指定noexcept(false)
更改它,我想知道其他函数。
c++ - 使用 noexcept 作为 lambda 修饰符或参数约束
修饰符可以noexcept
应用于 lambda 表达式吗?如果是这样,怎么做?
可以noexcept
对函数参数进行约束吗?例如,在下面的代码中,回调函数必须是什么意思noexcept
?
这几乎可以用下面的代码来完成,但我想知道是否有一种方法可以使用上述替代方法。
当然,这里的问题是,f_async
如果noexcept(false)
回调是noexcept(false)
- 我想做出一个更强有力的声明,那f_async
就是always noexcept
,这意味着它只有在使用noexcept
回调时才可调用。
c++ - g++-4.8.1 认为显式声明的没有异常规范的析构函数总是 noexcept(true)
考虑以下程序:
有了g++-4.8.1
,就出现了静态断言失败Explicit
——好像是这样认为~Explicit()
的noexcept
。这不符合我的期望。根据§12.4.3:
没有异常规范的析构函数声明被隐式认为具有与隐式声明相同的异常规范
这里有趣的是,检查的Implicit
行为似乎符合我对 §15.4.14 的解释(通过 §12.4.7)。
...如果f是一个...析构函数...它的隐式异常规范指定...
noexcept(true)
如果它直接调用的每个函数都不允许异常,则 f 具有异常规范。
g++-4.7
缺乏is_nothrow_destructable
,我写了自己的来检查 4.7 中的行为。该程序似乎编译得很好。我保留完全错误的权利和我困惑的根源:
TL;DR:为什么g++-4.8.1
认为明确声明的没有异常规范的析构函数总是 noexcept(true)
?
更新:我打开了一个错误:57645。如果您确实需要解决此问题,可以向析构函数添加异常规范(如Thrower
示例中的 has)。
c++ - 将空指针传递给新位置
默认放置new
操作符在 18.6 [support.dynamic] ¶1 中声明,带有非抛出异常规范:
这个函数什么都不return ptr;
做,所以它是合理的noexcept
,但是根据 5.3.4 [expr.new] ¶15 这意味着编译器必须在调用对象的构造函数之前检查它是否返回 null:
-15-
[注意:除非使用非抛出异常规范(15.4)声明分配函数,否则通过抛出异常表示分配存储失败std::bad_alloc
(第15条,第18.6.2.1条);否则它返回一个非空指针。如果分配函数声明为不抛出异常规范,则返回 null 以指示分配存储失败,否则返回非空指针。——尾注]如果分配函数返回null,则不进行初始化,不调用deallocation函数,new-expression的值为null。
在我看来(特别是针对放置new
,而不是一般而言)这个空检查是一个不幸的性能损失,尽管很小。
我一直在调试一些代码,其中new
在对性能非常敏感的代码路径中使用放置以改进编译器的代码生成,并且在程序集中观察到 null 检查。new
通过提供使用抛出异常规范(即使它不可能抛出)声明的特定于类的放置重载,条件分支被删除,这也允许编译器为周围的内联函数生成更小的代码。说放置new
函数可以抛出,即使它不能抛出,结果是明显更好的代码。
所以我一直想知道放置new
案例是否真的需要空检查。它可以返回 null 的唯一方法是如果你将它传递给 null。尽管有可能并且显然是合法的,但可以这样写:
我不明白为什么这会有用,我建议如果程序员在使用放置之前必须明确检查 null 会更好,new
例如
有没有人需要放置new
来正确处理空指针的情况?(即没有添加ptr
一个有效内存位置的显式检查。)
我想知道禁止将空指针传递给默认放置new
函数是否合理,如果不是,是否有更好的方法来避免不必要的分支,而不是试图告诉编译器该值不为空,例如
或者:
注意这个问题是故意标记为微优化,我并不是建议您new
为所有类型重载放置以“提高”性能。这种效果在一个非常具体的性能关键案例中被注意到,并且基于分析和测量。
更新: DR 1748使使用带有新位置的空指针成为未定义行为,因此不再需要编译器进行检查。
c++ - 为什么“动态异常”保证会导致开销?
在 C++11 中,这已被弃用:
并替换为
在本文中解释了这样做的原因(其中归结为同一件事)是
C++ 异常规范是在运行时而不是在编译时检查的,因此它们不提供程序员保证所有异常都已被处理。
虽然这对我来说确实有意义,但我不明白为什么throw()
首先动态检查,或者为什么noexcept
不提供异常保证,而不是调用std::terminate
而不是正常的堆栈展开(这并不是真正的可靠保证 IMO)。
难道不能在编译期间检查是否抛出异常,如果发生这种情况,编译会失败吗?在我看来,基本上有三种情况:
使用 C++ 中的模板为每种类型实例化,编译应用程序无论如何都需要永远 - 那么为什么不更改noexcept
以强制编译器检查在编译期间是否抛出异常呢?
noexcept
我看到的唯一困难是一个函数可能会或可能不会抛出取决于运行时状态 - 但在我看来,无论如何都不应该允许该函数调用自己。
我是否遗漏了一些东西,或者是为了不进一步增加编译时间,还是为了让编译器开发人员轻松一些?
c++ - 错误:预期的';' 在“无例外”之前
我想我没有忘记";" ..
我不知道为什么我有这个错误
编译者说它来自:
c++ - Should std::chrono::steady_clock::now be noexcept?
I've noticed that std::chrono::steady_clock::now
has the noexcept
specifier in the documentation at cplusplus.com. However, I haven't found any provision for this in the latest C++11 draft (unfortunately I don't have a copy of the standard).
Is it a mistake in the cplusplus.com documenation or should std::chrono::steady_clock::now
have the noexcept
specifier?
c++ - 如何正确使用 noexcept 运算符
我已经实现了一个智能指针,它使用调用内部对象方法的代理函数存储类型为 T 的对象:
但是我发现了一个奇怪的问题——当一个成员函数中产生了一个 std::exception 时,程序就会终止,即使代理函数是在一个 try 块中被调用的。所以我的问题是:使用 noexcept 运算符是否正确,如果不是,在这种情况下我应该如何使用它?
c++ - 永远不要将涉及动态内存分配的函数注释为 noexcept?
假设您有一个通常永远不会失败的函数,例如:
原则上,这将是noexcept
. 但是,实现很可能涉及动态内存管理,因此在使用运算符分配内存时,它总是会抛出std::bad_allocnew
。
是否建议将函数注释为 noexcept?
从实际的角度来看,以合理的方式处理内存不足的情况是极其困难的。大多数程序只是假设有足够的可用内存。std::terminate
如果noexcept
函数 throws会发生调用,std::bad_alloc
在这种情况下似乎是合理的。
对我来说noexcept
是某种形式的文档。这是您(或优化器)可以安全地假设此函数永远不会抛出的承诺。如果您正在编写一个不关心内存不足情况的应用程序,那么它仍然是一个有效的假设。
我想最安全的建议是永远不要使用noexcept
如果std::bad_alloc
可以抛出异常。另一方面,我想知道如果noexcept
您不关心内存不足的情况(即,如果std::terminate
可以的话),是否有任何优势可以使用。
c++11 - noexcept(expression) - 其中 expression 是实际抛出的 noexcept 函数
查看 C++11 Spec (n3485) 第 5.3.7 节,注释 3 表示 noexcept(expr) 的结果为假,如果:
... 对函数的潜在求值调用... 没有非抛出异常规范 ... 潜在求值 throw 表达式 ... 潜在求值 dynamic_cast ... 潜在求值typeid 表达式...
“潜在评估”是否意味着它向下钻取(一点也不?一点点?)以确定其中一个条件是否会导致错误?
我发现(在测试代码中,而不是应用程序中)一个声称为 noexcept 但实际上确实抛出(即使在所有情况下)的函数仍将被视为 noexcept。是误解了规范还是以下示例中的代码全错了?
根据 Clang 3.3,这个测试表明 calculate() 不会抛出。