The following code: // https://godbolt.org/z/tWa2dr int main() { extern long double ld; double d{ld}; } is invalid according to [dcl.list.init]3.9 (http://eel.is/c++draft/dcl.init.list#3.9): regardless of a target's actual size for these types, long double -> double is considered a narrowing conversion [dcl.list.init]/7 (http://eel.is/c++draft/dcl.init.list#7.2), and the compiler cannot use the constant expression loophole here. Clang and MSVC correctly error on this. Actual behaviour: GCC only warns (-Wnarrowing), even with -pedantic. Expected behaviour: GCC does not accept this code. This bug exists in all compiler versions, afaict (4.7.4, 4.8.3, 9.1, trunk).
The standard requires a diagnostic for this, and GCC issues a diagnostic. The behaviour is by design and not a bug. Use -Werror=narrowing if you want an error.
(In reply to Jonathan Wakely from comment #1) > The behaviour is by design And documented, see https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Dialect-Options.html#index-Wnarrowing "For C++11 and later standards, narrowing conversions are diagnosed by default, as required by the standard. A narrowing conversion from a constant produces an error, and a narrowing conversion from a non-constant produces a warning, but -Wno-narrowing suppresses the diagnostic. Note that this does not affect the meaning of well-formed code; narrowing conversions are still considered ill-formed in SFINAE contexts."
Indeed, I didn't check that it actually fails in SFINAE. Sorry for that. This works: // https://godbolt.org/z/EfJmS4 #include <utility> #include <experimental/type_traits> template <typename From, typename To> using nonnarrowing_test = decltype(To{std::declval<From&>()}); template <typename From, typename To> using is_narrowing = std::negation<std::experimental::is_detected<nonnarrowing_test, From, To>>; static_assert(is_narrowing<long double, double>{}); static_assert(!is_narrowing<double, long double>{});
*** This bug has been marked as a duplicate of bug 55783 ***
Hi, This specific bug needs to be reopened: GCC incorrectly accepts long double to double in list initializations, and generates no warnings, on architectures where long double is the same as double. Testcases: On ARM: https://godbolt.org/z/SRg3fr On X86-64 also passing -mlong-double-64: https://godbolt.org/z/GnRkHC SFINAE contexts are affected as well: https://godbolt.org/z/icMA3k Clang, MSVC reject the code.
That's a different bug, so thanks for filing it separately (PR 94590).