Inconsistent behaviour across compilers in regard to instantiation of a template in a discarded if constexpr(false) statement

Definitively a bug of MSVC. A bug report exist and has been reportedly fixed in Visual Studio 2019 Preview.


if constexpr is standardized in [stmt.if]/2:

If the if statement is of the form if constexpr, the value of the condition shall be a contextually converted constant expression of type bool; this form is called a constexpr if statement.

This applies.

If the value of the converted condition is false, the first substatement is a discarded statement, otherwise [...].

It also applies, making in your program { std::optional<T> val; } a discarded statement.

During the instantiation of an enclosing templated entity (ndYSC Bar<void, int>), if the condition is not value-dependent after its instantiation, the discarded substatement (if any) is not instantiated.


Along with @YSC's answer, also relevant is [temp.inst]/10:

An implementation shall not implicitly instantiate a function template, a variable template, a member template, a non-virtual member function, a member class, a static data member of a class template, or a substatement of a constexpr if statement , unless such instantiation is required.