c++language-lawyer

In a false `if constexpr` branch outside of a template, are bodies of called template functions instantiated or not?


The common wisdom is that if constexpr has no magic powers outside of a template or if the condition doesn't depend on a template parameter.

However under closer examination, it doesn't seem to be the case. First, [basic.def.odr]/12 says that entities used in a false if constexpr branch don't need to have definitions (regardless of being in a template).

And then [temp.inst]/5 says that if a function definition isn't needed, it's not instantiated.

Now consider the following example:

template <typename T>
int f()
{
    T *ptr;
    return 0;
}

template <typename T>
void g()
{
    int x = T::x;
}

int main()
{
    if constexpr (false)
    {
        int x = f<int &>();  // only clang 19+ errors
        g<int>();            // ok
    }
}

Here the g() call is accepted by all compilers, while the f() call is rejected by Clang 19+ only.

So is this program correct or not? To me it seems that both calls should compile, so we've reported a Clang bug, but are now being told that it works as intended.

What am I missing?


Solution

  • Since the bug did get accepted and fixed after all, I assume my interpretation (as explained in the question) was correct, and this is supposed to compile.