Normally, I can place function calls after std::unreachable, and it has no effect. This works on MSVC, Clang, and GCC, except with GCC there is an extra detail that makes it fail compilation:
#include <iostream>
#include <utility>
int anotherFunc()
{
return 42;
}
int my_func()
{
std::string s; // IF std::string APPEARS HERE YOU CAN NO LONGER CALL
// ANOTHER FUNCTION AFTER std::unreachable
if (rand() % 2 == 0)
return {};
std::unreachable();
anotherFunc(); //THIS WON'T COMPILE IF std::string APPEARS ABOVE
}
int main(int argc, char* argv[])
{
my_func();
}
<source>: In function 'int my_func()':
<source>:24:1: error: control reaches end of non-void function [-Werror=return-type]
24 | }
| ^
cc1plus: some warnings being treated as errors
Here is a comparison of MSVC and Clang and GCC.
It's only in GCC that a function call AFTER std::unreachable won't compile IF an object appears constructed on the stack beforehand.
But, here's an extra interesting detail. I tried with a whole bunch of different objects, and std::string, std::vector and std::unordered_map all failed to compile, but then I tried my own custom class and it compiled. So, it seems it won't compile only with standard library objects? This happens all the way to the newest GCC, 15.
1 Answer 1
The way the question is phrased is strange.
std::string s; // IF std::string APPEARS HERE YOU CAN NO LONGER CALL // ANOTHER FUNCTION AFTER std::unreachable
You were never able to call anything after std::unreachable() in the first place.
std::unreachable() invokes undefined behavior, so if you ever evaluate it,
it's completely unknown what would happen.
There is no guarantee that destructors run after std::unreachable().
I'm assuming you mean
I could normally place function calls after
std::unreachable()without getting a-Wreturn-typewarning.
The GCC warning you get is definitely a false positive.
I have reported this bug at https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120597
However, there's also very little reason to write the code the way you did.
You can suppress the GCC warning by putting std::unreachable(); at the end of the function instead of somewhere in the middle, and this would provide much more code clarity.
If anything after std::unreachable(); is undefined behavior anyway, why would you want to put function calls afterwards?
It's no surprise that this bug (based on my search) has not been reported yet.
Minimal reproducible example
Note that the minimal code necessary to produce a false positive for GCC is:
struct S { ~S(); };
int f();
int g() {
S s;
if (f()) return 0;
__builtin_unreachable();
f(); // warning: control reaches end of non-void function [-Wreturn-type]
}
You couldn't reproduce it with your own type because your struct MyType {}; is trivially destructible, so nothing happens when it goes out of scope.
I suppose GCC doesn't get confused about reaching the end of the function in that simpler scenario.
Comments
Explore related questions
See similar questions with these tags.
std::unreachable()is related to "control reaches end of non-void function" warning?std::unreachableinvokes UB, so I don't think there is any guarantee on the behavior (i.e. different compilers/versions can do different things).-Werrorisn’t "this won’t compile". Please rephrase to talk about warnings if that’s the point here.