boost::system::system_error是否为非抛出拷贝构造类型?如何消除抛出警告?
Is std::is_nothrow_copy_constructible<boost::system::system_error>::value supposed to be true?
Short answer: Not necessarily.
The noexcept status of boost::system::system_error's copy constructor depends on a few key factors:
- Boost version: Older Boost.System releases didn't prioritize noexcept guarantees for copy operations, while newer versions may optimize for this in limited cases.
- Custom error message presence: If your
system_errorinstance holds a dynamically allocated error string (e.g., constructed with astd::stringargument), its copy constructor must duplicate that string—an operation that can throw on memory allocation failure, so it can't be marked noexcept. - Compiler/stdlib implementation: Even without a custom message, while
error_code's copy is noexcept, some older toolchains might not propagate that guarantee to the enclosingsystem_errorcopy constructor.
When constructing system_error only with an error_code (no custom message), newer Boost versions may provide a noexcept copy constructor, but this isn't a universal guarantee across all configurations.
How to avoid non-throwing copy constructor warnings when throwing boost::system::system_error?
This warning fires because the compiler detects that copying the system_error could throw—a risky scenario (if the copy fails during exception propagation, the program terminates). Here are practical fixes:
1. Keep using temporary objects (your example is already on the right track!)
Your code:
boost::system::error_code ec; throw boost::system::system_error(ec);
Throwing a temporary allows the compiler to directly construct it in the exception storage area (skipping copy/move entirely via optimization). Even without this optimization, newer Boost versions mark system_error's move constructor as noexcept—so the exception object will be moved instead of copied, avoiding the warning.
2. Use std::move() for pre-existing instances
If you need to throw a already-created system_error, use std::move() to trigger the noexcept move constructor instead of the potentially non-noexcept copy constructor:
boost::system::system_error err(ec); throw std::move(err);
3. Skip custom error messages when possible
Constructing system_error only with an error_code keeps the object lightweight, minimizing the chance of a non-noexcept copy operation. This makes the copy faster and more likely to be noexcept.
4. Upgrade to a newer Boost version
Boost 1.70+ improved noexcept guarantees for system_error's move operations, which directly resolves this warning in most modern toolchains.
内容的提问来源于stack exchange,提问作者foijord

