I am trying to dig into implications of a function being inline
and stumbled upon this issue. Consider this small program (demo):
/* ---------- main.cpp ---------- */
void other();
constexpr int get()
{
return 3;
}
int main()
{
std::cout << get() << std::endl;
other();
}
/* ---------- other.cpp ---------- */
constexpr int get()
{
return 4;
}
void other()
{
std::cout << get() << std::endl;
}
When compiled without optimizations, the program yields the following output:
3
3
Which might be not what we want, but at least I can explain it.
- The compiler is not required to compute results of
constexpr
functions on compile time, so it decided to postpone it to runtime. constexpr
on functions impliesinline
- Our
get()
functions happened to have different implementations - We did not declare
get()
functions static - The linker must chose only one implementation of the
get()
function
And it so happened that the linker chose get()
from main.cpp
, which returned 3.
Now to the part I don't get. I simply changed get()
functions from constexpr
to consteval
. Now the compiler is required to compute the value during compile time, i.e. before the link time (right?). I'd expect get()
functions not to be present in object files at all.
But when I run it (demo), I have exactly the same output! How can this be?.. I mean yes, I understand that this is undefined behavior, but this is not the point. How come that the values that should have been computed on compile time interfered with other translation unit?
UPD: I am aware that this feature is listed as unimplemented in clang, but the question is applicable anyway. Is a conformant compiler allowed to exhibit such a behavior?