Created on 2017-06-27.00:00:00 last changed 100 months ago
Proposed resolution:
This wording is relative to N4659.
Edit [syserr.errcat.overview], class error_category synopsis, as indicated:
class error_category {
public:
constexpr error_category() noexcept;
virtual ~error_category();
error_category(const error_category&) = delete;
error_category& operator=(const error_category&) = delete;
virtual const char* name() const noexcept = 0;
virtual error_condition default_error_condition(int ev) const noexcept;
virtual bool equivalent(int code, const error_condition& condition) const noexcept;
virtual bool equivalent(const error_code& code, int condition) const noexcept;
virtual string message(int ev) const = 0;
bool operator==(const error_category& rhs) const noexcept;
bool operator!=(const error_category& rhs) const noexcept;
bool operator<(const error_category& rhs) const noexcept;
};
constexpr const error_category& generic_category() noexcept;
constexpr const error_category& system_category() noexcept;
Edit [syserr.errcat.objects] as indicated:
constexpr const error_category& generic_category() noexcept;[…]
constexpr const error_category& system_category() noexcept;[…]
Edit [syserr.errcode.overview], class error_code synopsis, as indicated:
class error_code {
public:
// [syserr.errcode.constructors], constructors
constexpr error_code() noexcept;
constexpr error_code(int val, const error_category& cat) noexcept;
template <class ErrorCodeEnum>
error_code(ErrorCodeEnum e) noexcept;
// [syserr.errcode.modifiers], modifiers
constexpr void assign(int val, const error_category& cat) noexcept;
template <class ErrorCodeEnum>
error_code& operator=(ErrorCodeEnum e) noexcept;
constexpr void clear() noexcept;
// [syserr.errcode.observers], observers
constexpr int value() const noexcept;
constexpr const error_category& category() const noexcept;
error_condition default_error_condition() const noexcept;
string message() const;
explicit operator bool() const noexcept;
private:
int val_; // exposition only
const error_category* cat_; // exposition only
};
Edit [syserr.errcode.constructors] as indicated:
constexpr error_code() noexcept;[…]
constexpr error_code(int val, const error_category& cat) noexcept;[…]
Edit [syserr.errcode.modifiers] as indicated:
constexpr void assign(int val, const error_category& cat) noexcept;[…]
constexpr void clear() noexcept;[…]
Edit [syserr.errcode.observers] as indicated:
constexpr int value() const noexcept;[…]
constexpr const error_category& category() const noexcept;[…]
[ 2017-07 Toronto Tuesday PM issue prioritization ]
NAD; This is a feature request; needs a paper.
The default constructor of error_code should be constexpr to enable constant initialization; as a practical matter, there are reports that it regularly shows up in profiles because clearing error codes is so frequent.
Suggested resolution:add constexpr to the declaration of system_category() in [syserr.errcat.overview] and [syserr.errcat.objects];
optionally, add constexpr to the declaration of generic_category() in the same two sections;
add constexpr to the default constructor of error_code in [syserr.errcode.overview] and [syserr.errcode.constructors];
optionally, add constexpr to the error_code(int val, const error_category& cat) constructor in the same two sections;
optionally, add constexpr to error_code::assign;
optionally, add constexpr to error_code::clear;
optionally, add constexpr to error_code::value;
optionally, add constexpr to error_code::category.
There was an objection that system_category() can't be made constexpr because it needs to "immortalize" the object so that it's not destroyed at process shutdown or module unload, in order for the error_code facility to remain usable. However, the following proof of concept shows how to achieve this and still make the function constexpr:
#include <new>
template<class _Ty>
union _Immortalizer
{ // constructs _Ty, never destroys
constexpr _Immortalizer(): __ty()
{
}
~_Immortalizer() noexcept {}
_Immortalizer(const _Immortalizer&) = delete;
_Immortalizer& operator=(const _Immortalizer&) = delete;
_Ty __ty;
};
struct error_category
{
virtual ~error_category() = default;
};
struct system_category_impl : public error_category
{
};
[[clang::require_constant_initialization]] static const _Immortalizer<system_category_impl> _System_category;
constexpr error_category const& system_category() noexcept
{
return _System_category.__ty;
}
struct error_code
{
int val_;
const error_category* cat_;
constexpr error_code() noexcept : val_(0), cat_(&system_category()) {}
constexpr int value() const noexcept { return val_; }
constexpr error_category const& category() const noexcept { return *cat_; }
};
constexpr error_code s_code;
static_assert(s_code.value() == 0);
static_assert(&s_code.category() == &system_category());
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2017-07-12 01:58:24 | admin | set | messages: + msg9355 |
| 2017-07-12 01:58:24 | admin | set | status: new -> nad |
| 2017-06-28 17:06:31 | admin | set | messages: + msg9308 |
| 2017-06-27 00:00:00 | admin | create | |