当标记为 的函数尝试调用noexcept未标记为 的函数时,GCC 或 Clang 中是否有一个标志会抛出编译时错误(或警告) noexcept?
noexcept如果不是,那么当您从先前标记的 funciton 中删除时,您应该如何判断代码的哪些部分受到影响noexcept?难道根本就没有办法吗?
有没有办法(编译器扩展是可接受的)包含 C 标头并将包含的 C 函数标记为noexcept,但不修改标头?
例如,我有一个 C 库及其头文件header.h。不会将任何 C++ 回调传递给它,因此它永远不会抛出异常。我可以将包含的 C 函数标记为noexcept或告诉编译器它们永远不会抛出异常,以便编译器不必生成未使用的代码并为调用者启用一些可能的优化吗?请注意,使用 C 库的 C++ 代码应该仍然能够使用异常(因此不能选择禁用整个程序的异常)。
extern "C" {
#include "header.h" // Is there a way to mark included C functions here as noexcept?
}
Run Code Online (Sandbox Code Playgroud) 我有以下代码:
struct S {
// conditional noexcept specification which depends on noexceptness of foo()
void bar() noexcept(noexcept(foo()));
// conditional noexcept specification (true)
void foo() noexcept(true);
};
Run Code Online (Sandbox Code Playgroud)
Clang 拒绝此代码,但 GCC 允许它(https://godbolt.org/z/nxqa5Tr1x):
<source>:2:34: error: exception specification is not available until end of class definition
2 | void bar() noexcept(noexcept(foo()));
|
Run Code Online (Sandbox Code Playgroud)
替换noexcept(true)为noexcept两个编译器都允许
noexcept(true)失败但是noexcept成功?注意:这个例子显然是最小的。我的实际用例是,我有一个clear()成员函数,仅在自定义容器中为noexceptif clear_impl()is 。noexcept
通过C++标准(当前草案http://isocpp.org/files/papers/N3690.pdf,sec 20.8.3就是这样一个地方),通过LLVM的libc ++标题,我发现"见下文"用作类型和异常规范.它似乎在没有类型存在时使用,但是使用2个单词短语而不是某种有效的标识符似乎很奇怪.
它是在标准或其他地方讨论的吗?为什么/如何使用它?
好吧,如果我使用RAII惯用语来管理某些上下文属性*,如果我在try块的开头裸体使用它,它是否会像我期望的那样工作?
换句话说,如果我有这个:
struct raii {
raii() {
std::cout << "Scope init"
<< std::endl; }
~raii() {
std::cout << "Scope exit"
<< std::endl; }
};
Run Code Online (Sandbox Code Playgroud)
......我成功地使用它:
{
raii do_the_raii_thing;
stuff_expecting_raii_context();
/* … */
}
Run Code Online (Sandbox Code Playgroud)
...如果我这样做,RAII实例将以相同的方式工作:
try {
raii do_the_raii_thing;
stuff_expecting_raii_context_that_might_throw();
/* … */
} catch (std::exception const&) {
/* … */
}
Run Code Online (Sandbox Code Playgroud)
这可能是一个愚蠢的问题,但我想在此检查自己的理智 - 我对noexcept保证的微妙之处以及其他与例外相关的细节感到模糊- 所以请原谅我的天真
[*]对于那些好奇的人来说,这是我在RAII管理的Python C-API狡猾的GIL(全球翻译锁),在我的具体案例中
鉴于以下类声明:
class phone_number
{
public:
explicit phone_number( std::string number ) noexcept( std::is_nothrow_move_constructible< std::string >::value );
}
phone_number::phone_number( std::string number ) noexcept( std::is_nothrow_move_constructible< std::string >::value )
: m_originalNumber{ std::move( number ) }
{
}
Run Code Online (Sandbox Code Playgroud)
std::terminate()如果从字符串构造函数抛出异常,下面的代码行是否会因为noexcept规范而立即调用?
const phone_number phone("(123) 456-7890");
Run Code Online (Sandbox Code Playgroud) 这个MWE可能看似人为,但失败的static_assert仍然令人惊讶:
#include <utility>
struct C {
void f() noexcept { }
using F = void(C::*)();
static constexpr F handler() noexcept {
return &C::f;
}
void g() noexcept(noexcept((this->*handler())())) {
}
};
int main() {
static_assert(noexcept(std::declval<C>().g()));
}
Run Code Online (Sandbox Code Playgroud)
Wandbox链接:https://wandbox.org/permlink/a8HSyfuyX1buGrbZ
我希望这可以用于Clang而不是GCC,因为它们在运算符noexcept的上下文中对"this"的处理方式不同.
该pop()方法std::priority_queue不宣noexcept,所以理论上可以抛出一个异常.但什么时候可能会抛出异常,那些异常会是什么?