Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to check if the function has a void return type

Tags:

c++

c++11

This very strange request came up ...

I need to do a compile time check whether the current function has a void return type or not and fail compilation if the return type is void.

I tried to do some magic with http://en.cppreference.com/w/cpp/types/result_of and decltype also, however I just cannot get closer to a solution.

#include <type_traits>

void other_func(void) { }

void test_maxi(void)
{
    typedef decltype(&::other_func) TYPE;
    static_assert(std::is_same<TYPE, void>::value, "not void"); 
}

int main() {
}

So here comes the question:

Is it possible to do this for the current function?

EDIT The return type check should go in a macro, since it will be used in several functions.

like image 835
Ferenc Deak Avatar asked Jul 07 '16 11:07

Ferenc Deak


Video Answer


1 Answers

You can implement compile-time checking if one string literal starts with another, and use the __PRETTY_FUNCTION__ macro, which is set to string literal that starts with function return type. You should check if this macro starts with void followed by 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 to be specific to GNU C++ Compiler, however, clang++ works fine since it defines this macro as well. If you are using another compiler, you should check if this macro is really being set, and if not, read compiler documentation in order to determine similar macro, e.g., __FUNCSIG__.

You can play around with #ifdef __PRETTY_FUNCTION__ ... to make this more portable between various compilers, but I believe this is a topic for another question.

like image 102
Anton K Avatar answered Sep 28 '22 05:09

Anton K