-
Notifications
You must be signed in to change notification settings - Fork 2
Home
The following list is a collection of corner cases that are known to fail with some specific compilers. These bugs don't have corresponding issues either because I'm not sure what is the right behaviour anyway, or because the bug is fixed in a more recent version of the problematic compiler, and I don't feel like fixing it in the older versions.
The following sample does not compile with GCC, the call to explicit_vs_implicit_brace_init
is considered ambiguous:
struct BraceInit { BraceInit() = default; };
struct ExplicitBraceInit { explicit ExplicitBraceInit() = default; };
constexpr int explicit_vs_implicit_brace_init(cruft::tight_pair<ExplicitBraceInit, ExplicitBraceInit>) { return 1; }
constexpr int explicit_vs_implicit_brace_init(cruft::tight_pair<BraceInit, BraceInit>) { return 2; }
// ERROR: ambiguous with GCC
explicit_vs_implicit_brace_init({{}, {}});
Clang and MSVC both pick the second overload.
Consider the following class:
struct PotentiallyThrowing
{
constexpr PotentiallyThrowing() noexcept(false) {};
};
Despite the noexcept(false)
, some compilers consider that std::is_nothrow_default_constructible_v<PotentiallyThrowing>
is true
, and that behaviour extends to cruft::tight_pair
when it wraps PotentiallyThrowing
. This is an issue with an old standard decision considering that constant expression were always noexcept
. This was changed back in C++17, but some compilers didn't adapt right away - most notably GCC prior to version 9 -, leading to this odd behaviour.
Prior to version 19.30, MSVC does not consider the piecewise constructor to be constexpr
when both elements of cruft::tight_pair
have the same type and are not eligible to be erased by EBCO. I don't know why and made no effort to circumvent that bug.