I have compiled and ran the following program in a C++17 compiler (Coliru). In the program, I declared an extern
variable, but did not define it. However, the compiler doesn't give a linker error.
#include <iostream>
extern int i; // Only declaration
int func()
{
if constexpr (true)
return 0;
else if (i)
return i;
else
return -1;
}
int main()
{
int ret = func();
std::cout<<"Ret : "<<ret<<std::endl;
}
Why doesn't the compiler give a linker error?
Because the variable isn't odr-used. You have a
constexpr if
there that always discards the branch that could use it.One of the points of
constexpr if
is that the discarded branch need not even compile, only be well-formed. That's how we can place calls to non-existing member functions in a discarded branch.Because the compiler produces compiler errors, the linker would yield linker errors ...
No, seriously:
is always true, so the compiler ignores the rest of the if-clause because it is never reached. So
i
is never used actually.In your case the variable is used in discarded statements only. However, even if we ignore that fact, C++ language specification still explicitly states that no diagnostic is required for missing definitions
The language specification understands that an optimizing compiler might be smart enough to eliminate all odr-uses of a variable. In that case it would be excessive and unnecessary to require the implementation to detect and report the potential ODR violations.
This has alrady been answered, but if you are interested, cppreference.com has exactly this example for constexpr if: