Only mark functions as `noexcept` when you can guarantee they won't throw exceptions under any circumstances. Common pitfalls include: 1. **Hidden allocations**: Operations like vector operations, `std::make_tuple`, or working with collections might allocate memory and throw.
Only mark functions as noexcept
when you can guarantee they won’t throw exceptions under any circumstances. Common pitfalls include:
std::make_tuple
, or working with collections might allocate memory and throw.noexcept
.For complex templated code, consider compile-time validation:
// Before marking a templated function as noexcept
template <typename DataDrivenPaintProperty, typename Evaluated>
static bool isConstant(const Evaluated& evaluated) noexcept {
// How do you know all operations here are truly noexcept?
return evaluated.template get<DataDrivenPaintProperty>().isConstant();
}
// Better: Add compile-time verification
template <typename DataDrivenPaintProperty, typename Evaluated>
static bool isConstant(const Evaluated& evaluated) noexcept {
using ReturnType = decltype(evaluated.template get<DataDrivenPaintProperty>());
static_assert(std::is_nothrow_invocable_v<decltype(&ReturnType::isConstant), ReturnType&>,
"isConstant() must be noexcept");
return evaluated.template get<DataDrivenPaintProperty>().isConstant();
}
When in doubt, err on the side of caution and omit noexcept
. Incorrect noexcept
specifications can lead to program termination if an exception is thrown, which is worse than having a potentially throwing function not marked as noexcept
.
Enter the URL of a public GitHub repository