preface
The noexcept keyword is an exception handling keyword for C + + only.
stay Last In, we learned about exception throwing, catching and overloading. Consider the following questions:
- If a function (possibly from a third-party library) throws an exception, how do you know the type it may throw?
Looking at the source code is indeed a way, but what if the function body is long or the function is nested?
What if the third-party library function has only function declaration and no function implementation?
This brings us to today's topic - exception specification specifier
What is an exception specification?
The exception specification is used to describe the types of exceptions that may be thrown by the function. As a modifier of the function declaration, it follows the parameter list [()] and is consistent with the static function description const 1 Put it together.
grammar
Its standard syntax is:
[adding] ret-type func-name( list ) [adding] throw( exception ) ;
Among them, throw() is preceded by a general function declaration (or implementation). The data type written in throw indicates the exceptions that may be thrown by the function, such as:
void func1() throw(); //Indicates that no exceptions are thrown void func2() throw(int); //int type exceptions may be thrown void func3() throw(const char * , float); //C-wind string and single precision floating-point exceptions may be thrown void func4() throw(thread); //thread object exceptions may be thrown
As you can see, no type is written in throw(), which means that the function does not throw any exceptions.
significance
- With exception specifications, when you need to understand function exceptions, you just need to open the declaration at a glance.
- Maintainers should not throw any exception types other than specifiers.
- The specifier is part of the function interface and is used to explain how to use the function correctly.
Exceptions beyond specifications
Consider the following codes:
void func() throw(int){ throw 'x';//It does not conform to the abnormal specification } int main(){ try{ func(); } catch(int e){ cout<<"exception in int!\n"; } catch(char e){ cout<<"exception in char!\n"; } return 0; }
How does the compiler react? The following is a list of reactions that do not match the compiler.
- BCC:
Abnormal program termination
- g++:
terminate called after throwing an instance of 'char'
- VS2019,VC:
exception in char!
- Most online compilers:
warning: dynamic exception specifications are deprecated in C++11 [-Wdeprecated] 3 | void func() throw(int) | ^~~~~ terminate called after throwing an instance of 'char' Aborted (core dumped)
It can be seen that except VS and VC, most compilers will directly reject non-standard exception throwing. Because this is the C++11 specification.
noexcept keyword
Note: the noexcept keyword can only be used for C + +.
This keyword is added in C++11 to replace the throw() specifier. Indicates that the function will not throw any exceptions.
Its standard form is:
ret-type func_name( [params] ) [adding...] noexcept( noexcept(exception) )
The () after the first noexcept is a Boolean expression, indicating that the function is noexcept (that is, it is throw()) if and only if the Boolean value is true.
After the first noexcept (...) It can be omitted, which is equivalent to noexcept(true). (indicates that no exception will be thrown at any time)
The second noexcept(...) is similar to a function. Its parameter must be a function execution statement (parenthesis, such as func()), indicating whether to check whether the function throws an exception.
The following function declaration indicates that func() does not throw an exception if and only if funcc() does not throw an exception 2:
void func() noexcept( noexcept(funcc()) );
Abnormal transitivity
Use compilers other than Vc and VS to execute the following programs (because VC and VS do not comply with C++11 exception specification):
#include<iostream> using namespace std; void funcc(){ throw 114514; } void func() noexcept//No exception will be thrown { funcc();//Throw an exception in another function } int main(){ try{ func(); } catch(int err){ cerr<<"exception!\n"; } return 0; }
terminate called after throwing an instance of 'int' Aborted (core dumped)
It is not difficult to see that exceptions are passed. A function is noexcept if and only if its function body, called functions and methods do not throw exceptions. Even if an exception is thrown in the called function, it is not noexcept.
Change the above procedure to:
#include<iostream> using namespace std; void funcc(){ throw 114514; } void func() /* [-] *///noexcept /* [+] */ noexcept( noexcept(funcc()) ) { funcc(); } int main(){ try{ func(); } catch(int err){ cerr<<"exception!\n"; } return 0; }
#(normal operation) exception!
@Haohaocppdebugger
2021/12/21
THANK YOU !
More articles
- [C + + Keywords] C + + exception handling | throw, try, catch exception handling keywords
- C + + exception handling | unexpected() function
Static function description: the modifier before the function body {} (or before the end of the declaration) indicates that the function cannot modify variables. ↩︎
There are two possibilities:
1.func() calls funcc(), and funcc() may throw exceptions, which is equivalent to a white list of exceptions thrown.
2.func() function includes (or is included, or is similar to) funcc(). Therefore, as long as funcc() does not make an error, func() must be OK, that is, the two are unrelated functions. ↩︎