mirror of
https://gitlab.com/fbb-git/cppannotations
synced 2024-11-16 07:48:44 +01:00
removed remaining throw lists
This commit is contained in:
parent
77df8a59c5
commit
ed300494ed
10 changed files with 34 additions and 202 deletions
|
@ -3,10 +3,12 @@ Add content to section first: std::byte
|
|||
Add weak_ptr
|
||||
|
||||
Mention namespace chrono_literals
|
||||
std::option
|
||||
std::iota
|
||||
|
||||
coroutines
|
||||
|
||||
std::ranges
|
||||
std::jthread
|
||||
|
||||
rm annotations/OBS/ entries
|
||||
|
||||
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#define VERSION "12.0.0-pre"
|
||||
#define VERSION "12.0.0-isn"
|
||||
#define YEARS "1994-2021"
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
C++-annotations (12.0.0-isn)
|
||||
|
||||
* throw(typelist) specifications were removed from the language, and the
|
||||
section covering throw(typelist) was removed from the C++ Annotations.
|
||||
|
||||
C++-annotations (11.6.0)
|
||||
|
||||
* Added stl/optional.yo covering std::optional
|
||||
|
|
|
@ -89,7 +89,7 @@ not to use tt(noexcept) in your code:
|
|||
merely means that if such a function throws an exception
|
||||
tt(std::terminate) rather tha tt(std::unexpected) is called.
|
||||
it() Functions previously provided with an empty throw list (tt(throw()))
|
||||
should now be provided with tt(noexcept(true)).
|
||||
should be provided with tt(noexcept).
|
||||
it() tt(noexcept) specifications are required when using the following std
|
||||
traits (declared in the tthi(type_traits) header file):
|
||||
itemization(
|
||||
|
|
|
@ -86,7 +86,7 @@
|
|||
}
|
||||
return (*this);
|
||||
}
|
||||
Type &operator[](size_t index) throw(char const *)
|
||||
Type &operator[](size_t index)
|
||||
{
|
||||
if (index > (finish - start))
|
||||
throw "Vector array index out of bounds";
|
||||
|
|
|
@ -27,11 +27,8 @@ includefile(exceptions/catch)
|
|||
subsect(The default catcher)
|
||||
includefile(exceptions/defaultcatch)
|
||||
|
||||
sect(Declaring (deprecated) exception throwers)
|
||||
includefile(exceptions/declaring)
|
||||
|
||||
subsect(noexcept)
|
||||
includefile(exceptions/noexcept)
|
||||
sect(Functions that cannot throw exceptions: the `noexcept' keyword)
|
||||
includefile(exceptions/noexcept)
|
||||
|
||||
lsect(IOEXCEPTIONS)(Iostreams and exceptions)
|
||||
includefile(exceptions/iostreams)
|
||||
|
|
|
@ -1,83 +0,0 @@
|
|||
Once a function has been defined it's commonly called from other functions. If
|
||||
called functions are not defined in the same source file as calling functions
|
||||
the called functions must be declared, for which header files are commonly
|
||||
used.
|
||||
|
||||
The called functions may throw exceptions. When such functions are declared
|
||||
their declarations may specify a (now deprecated, see also section
|
||||
ref(NOEXCEPT)) hi(throw list) emi(function throw list) or
|
||||
emi(exception specification list) specifying the types of the exceptions
|
||||
that can be thrown by the called function. For example, a function that may
|
||||
throw `tt(char *)' and `tt(int)' exceptions can be declared as
|
||||
verb( void exceptionThrower() throw(char *, int);)
|
||||
|
||||
Function throw lists immediately follow the function header (and their
|
||||
specifications also follow possible tt(const) specifiers). Throw lists
|
||||
specify zero or more, comma separated, types, using the following syntax:
|
||||
verb( throw ()
|
||||
throw (type)
|
||||
throw (type1, type2, type3 ...))
|
||||
|
||||
where the ellipsis indicates any number of additional, comma separated,
|
||||
type specifications.
|
||||
|
||||
To indicate that a function is guaranteed not to throw exceptions an
|
||||
i(empty function throw list) can be used. E.g.,
|
||||
verb( void noExceptions() throw ();)
|
||||
|
||||
In all cases, the function header used in the function definition must
|
||||
exactly match the function header used in the declaration, including a
|
||||
possibly empty function throw list.
|
||||
|
||||
Once a function throw list has been specified its function may only throw
|
||||
exceptions of the types mentioned in its throw list. A emi(run-time error)
|
||||
occurs if such a function throws exceptions of types not specified in its
|
||||
function throw list. Example: the function tt(charPintThrower) shown below
|
||||
clearly throws a tt(char const *) exception. Since, according to its function
|
||||
throw list, tt(intThrower) may throw an tt(int) exception, the function throw
|
||||
list of tt(charPintThrower) must em(also) contain tt(int).
|
||||
verbinclude(-a examples/throwlist.cc)
|
||||
|
||||
A function without a throw list may throw any kind of exception. Without
|
||||
a function throw list the program's designer is responsible for providing the
|
||||
correct handlers.
|
||||
|
||||
For various reasons declaring exception throwers is now deprecated. Declaring
|
||||
exception throwers does not imply that the em(compiler) checks whether an
|
||||
improper exception is thrown. Rather, the function for which a function throw
|
||||
list has been specified is surrounded by additional code in which the actually
|
||||
thrown exception is inspected: if the exception is of a type that is listed in
|
||||
the function's throw list then that exception is rethrown; otherwise a
|
||||
run-time error is thrown. Instead of compile-time checks you get run-time
|
||||
overhead, resulting in additional code (and execution time) that is added to
|
||||
the function's code. One could write, e.g.,
|
||||
verb( void fun() throw (int)
|
||||
{
|
||||
// code of this function, throwing exceptions
|
||||
})
|
||||
|
||||
but the function would be compiled to something like this (cf.
|
||||
section ref(FUNTRY) for the use of tt(try) immediately following the
|
||||
function's header and section ref(STDEXC) for a description of
|
||||
ti(bad_exception)):
|
||||
verb( void fun()
|
||||
try // this code resulting from throw(int)
|
||||
{
|
||||
// the function's code, throwing all kinds of exceptions
|
||||
}
|
||||
catch (int) // remaining code resulting from throw(int)
|
||||
{
|
||||
throw; // rethrow the exception, so it can be caught by the
|
||||
// `intended' handler
|
||||
}
|
||||
catch (...) // catch any other exception
|
||||
{
|
||||
throw bad_exception{};
|
||||
})
|
||||
|
||||
Run-time overhead results because the number of thrown and caught
|
||||
exceptions are doubled. If no function throw list is specified then a thrown
|
||||
tt(int) is simply caught by its intended handler; if a function throw list has
|
||||
been specified the thrown tt(int) is em(first) caught by the `safeguarding'
|
||||
handler added to the function. In there it is em(rethrown) whereafter it is
|
||||
caught by its intended handler.
|
|
@ -1,40 +0,0 @@
|
|||
#include <iostream.h>
|
||||
|
||||
void intThrower() throw(int);
|
||||
void charP_IntThrower() throw (char *, int);
|
||||
|
||||
void intThrower(int x) throw (int)
|
||||
{
|
||||
if (x)
|
||||
throw x;
|
||||
}
|
||||
|
||||
void charP_IntThrower() throw (char *, int)
|
||||
{
|
||||
int
|
||||
x;
|
||||
cout << "Enter an int: ";
|
||||
cout.flush();
|
||||
cin >> x;
|
||||
|
||||
intThrower(x);
|
||||
throw "from charP_IntThrower() with love";
|
||||
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
try
|
||||
{
|
||||
charP_IntThrower();
|
||||
}
|
||||
catch (char *message)
|
||||
{
|
||||
cout << "Text exception: " << message << '\n';
|
||||
}
|
||||
catch (int value)
|
||||
{
|
||||
cout << "Int exception: " << value << '\n';
|
||||
}
|
||||
return (0);
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
void charPintThrower() throw(char const *, int);
|
||||
|
||||
class Thrower
|
||||
{
|
||||
public:
|
||||
void intThrower(int) const throw(int);
|
||||
};
|
||||
|
||||
void Thrower::intThrower(int x) const throw(int)
|
||||
{
|
||||
if (x)
|
||||
throw x;
|
||||
}
|
||||
|
||||
void charPintThrower() throw(char const *, int)
|
||||
{
|
||||
int x;
|
||||
|
||||
cerr << "Enter an int: ";
|
||||
cin >> x;
|
||||
|
||||
Thrower().intThrower(x);
|
||||
throw "this text is thrown if 0 was entered";
|
||||
}
|
||||
|
||||
void runTimeError() throw(int)
|
||||
{
|
||||
throw 12.5;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
try
|
||||
{
|
||||
charPintThrower();
|
||||
}
|
||||
catch (char const *message)
|
||||
{
|
||||
cerr << "Text exception: " << message << '\n';
|
||||
}
|
||||
catch (int value)
|
||||
{
|
||||
cerr << "Int exception: " << value << '\n';
|
||||
}
|
||||
try
|
||||
{
|
||||
cerr << "Generating a run-time error\n";
|
||||
runTimeError();
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
cerr << "not reached\n";
|
||||
}
|
||||
}
|
|
@ -1,16 +1,24 @@
|
|||
Although function throw lists are deprecated, its younger cousin ti(noexcept)
|
||||
is not. The tt(noexcept) keyword is used where previously empty function throw
|
||||
lists were used (cf. section ref(SYSTEMERROR) for examples where tt(noexcept)
|
||||
is used). Like empty function throw lists you incur some run-time overhead,
|
||||
but tt(noexcept) is more strict than empty function throw lists when
|
||||
violations are observed. When violating function throw list specifications a
|
||||
tt(std::unexpected) exception is thrown, when violating tt(noexcept) it
|
||||
results in tt(std::terminate), ending the program.
|
||||
Once a function has been defined it's often called from other functions. If
|
||||
called functions are not defined in the same source file as calling functions
|
||||
the called functions must be declared, for which header files are often
|
||||
used. Those called functions might throw exceptions, which might be
|
||||
unacceptible to the function calling those other functions. E.g., functions
|
||||
like tt(swap) and destructors may not throw exceptions.
|
||||
|
||||
In addition, tt(noexcept) can be given an argument that is evaluated
|
||||
compile-time: if the evaluation returns tt(true) then the tt(noexcept)
|
||||
requirement is used; if the evaluation returns tt(false), then the
|
||||
tt(noexcept) requirement is ignored. Examples of this advanced use of
|
||||
Functions that may not throw exceptions can be declared and defined by
|
||||
specifying the ti(noexcept) keyword (see section ref(SYSTEMERROR) for examples
|
||||
of function declarations specifying tt(noexcept)).
|
||||
|
||||
When using tt(noecept) there's a slight run-time overhead penalty because the
|
||||
function needs an over-all tt(try-catch) block catching any eception that
|
||||
might be thrown by its (called) code. When an exception is caught (violating
|
||||
the tt(noexcept) specification) then the tt(catch) clause calls
|
||||
tt(std::terminate), ending the program.
|
||||
|
||||
In addition to using a plain tt(noexcept), it can also be given an argument
|
||||
that is evaluated compile-time: if the evaluation returns tt(true) then the
|
||||
tt(noexcept) requirement is used; if the evaluation returns tt(false), then
|
||||
the tt(noexcept) requirement is ignored. Examples of this advanced use of
|
||||
tt(noexcept) are provided in section ref(NOEXCEPT).
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue