mirror of
https://github.com/boostorg/system.git
synced 2025-07-30 04:27:14 +02:00
Rename 'Usage Examples' to 'Usage', add another subsection
This commit is contained in:
@ -5,10 +5,10 @@ https://www.boost.org/LICENSE_1_0.txt
|
|||||||
////
|
////
|
||||||
|
|
||||||
[#usage]
|
[#usage]
|
||||||
# Usage Examples
|
# Usage
|
||||||
:idprefix: usage_
|
:idprefix: usage_
|
||||||
|
|
||||||
All of the following examples assume that these lines
|
All of the following code snippets assume that these lines
|
||||||
```
|
```
|
||||||
#include <boost/system.hpp>
|
#include <boost/system.hpp>
|
||||||
namespace sys = boost::system;
|
namespace sys = boost::system;
|
||||||
@ -610,3 +610,67 @@ sys::result<std::size_t> file_copy( file& src, file& dest )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Testing for Specific Error Conditions
|
||||||
|
|
||||||
|
Let's suppose that we have called a function that signals failure
|
||||||
|
using `error_code`, we have passed it an `error_code` variable `ec`,
|
||||||
|
and now for some reason want to check whether the function has
|
||||||
|
failed with an error code of `EINVAL`, "invalid argument".
|
||||||
|
|
||||||
|
Since `error_code` can be compared for equality, our first instict
|
||||||
|
might be `if( ec == error_code( EINVAL, generic_category() )`.
|
||||||
|
|
||||||
|
This is wrong, and we should never do it.
|
||||||
|
|
||||||
|
First, under POSIX, the function might have returned `EINVAL` from
|
||||||
|
the system category (because the error might have been returned by
|
||||||
|
an OS API, and not by the function itself, as was the case in our
|
||||||
|
`read` and `write` implementations.)
|
||||||
|
|
||||||
|
Since `error_code` comparisons are exact, `EINVAL` from the generic
|
||||||
|
category does not compare equal to `EINVAL` from the system category.
|
||||||
|
|
||||||
|
(And before you start thinking about just comparing `ec.value()` to
|
||||||
|
`EINVAL`, read on.)
|
||||||
|
|
||||||
|
Second, under Windows, the function might have returned `error_code(
|
||||||
|
ERROR_INVALID_PARAMETER, system_category() )`. As we have already
|
||||||
|
mentioned, the integer error values in the system category under
|
||||||
|
Windows are completely unrelated to the integer `errno` values.
|
||||||
|
|
||||||
|
The correct approach is to compare `ec` not to specific error codes,
|
||||||
|
but to `error_condition( EINVAL, generic_category() )`. Error
|
||||||
|
conditions are a platform-independent way to represent the meaning
|
||||||
|
of the concrete error codes. In our case, all error codes, under
|
||||||
|
both POSIX and Windows, that represent `EINVAL` will compare equal
|
||||||
|
to `error_condition( EINVAL, generic_category() )`.
|
||||||
|
|
||||||
|
In short, you should never compare error codes to error codes, and
|
||||||
|
should compare them to error conditions instead. This is the purpose
|
||||||
|
of the `error_condition` class, which is very frequently misunderstood.
|
||||||
|
|
||||||
|
Since
|
||||||
|
|
||||||
|
```
|
||||||
|
if( ec == sys::error_condition( EINVAL, sys::generic_category() ) )
|
||||||
|
{
|
||||||
|
// handle EINVAL
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
is a bit verbose, Boost.System provides enumerator values for the
|
||||||
|
`errno` values against which an error code can be compared directly.
|
||||||
|
|
||||||
|
These enumerators are defined in <<#ref_errc,`<boost/system/errc.hpp>`>>,
|
||||||
|
and enable the above test to be written
|
||||||
|
|
||||||
|
```
|
||||||
|
if( ec == sys::errc::invalid_argument )
|
||||||
|
{
|
||||||
|
// handle EINVAL
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
which is what one should generally use for testing for a specific error
|
||||||
|
condition, as a best practice.
|
||||||
|
Reference in New Issue
Block a user