You can implement compile-time checking if one string literal starts from another, and use the __PRETTY_FUNCTION__ macro, which is set to a string literal that starts with the type of the returned function. You should check if this macro starts with void followed by a space.
This code compiles fine:
constexpr bool startsWith(const char* a, const char* b) { return *a == *b && (*(a + 1) == '\0' || startsWith(a + 1, b + 1)); } int f() { static_assert(!startsWith("void ", __PRETTY_FUNCTION__), "not void"); return 1; } int main() { }
If you change f return type to void :
constexpr bool startsWith(const char* a, const char* b) { return *a == *b && (*(a + 1) == '\0' || startsWith(a + 1, b + 1)); } void f() { static_assert(!startsWith("void ", __PRETTY_FUNCTION__), "not void"); } int main() { }
static_assert will fire.
The __PRETTY_FUNCTION__ macro seems specific to the GNU C ++ compiler, however, clang++ works just fine, as it also defines this macro. If you use a different compiler, you should check if this macro is installed, and if not, read the compiler documentation to determine similar macros, for example, __FUNCSIG__ .
You can play with #ifdef __PRETTY_FUNCTION__ ... to make it more portable between different compilers, but I think this is a topic for another question.
Anton K
source share