Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to define macro function returns void or else in C++

Tags:

c++

macros


I defined following two function macro to check exit flag in my thread class.

//use this in run()
#define CHECK_EXIT  if( exitFlag_ ) {\
    //do something\
    return;\
}\

//use this in function
#define CHECK_EXIT_IN_FUNC  if( exitFlag_ ) {\
    //do something\
    return false;\
}\

I had to define them separately because returning value is different.
Can I define it in one macro?
I googled, but couldn't find answer.
Thanks for any advice.

like image 566
Winter Singha Avatar asked Dec 25 '22 05:12

Winter Singha


2 Answers

You can use a variadic macro. Pass in nothing if you don't want to return anything after the check.

#define CHECK_EXIT(...) CHECK_EXIT_(_, ##__VA_ARGS__)
#define CHECK_EXIT_(...) CHECK_EXIT_X(__VA_ARGS__, _1, _0)(__VA_ARGS__)
#define CHECK_EXIT_X(_0, _1, X, ...) CHECK_EXIT ## X
#define CHECK_EXIT_0(_) do if (exit_flag_) { /*...*/ return; } while(0)
#define CHECK_EXIT_1(_, R) do if (exit_flag_) { /*...*/ return (R); } while(0)

void test_0 () {
    bool exit_flag_ = true;
    CHECK_EXIT();
}

int test_1 () {
    bool exit_flag_ = true;
    CHECK_EXIT(0);
    return 1;
}

I used a very simplified version of the argument counting trick described in a different answer. I am able to simplify it because I rely on a GCC extension (##__VA_ARGS__) to remove the trailing comma if the variable arguments expansion is empty. Use the full blown version if you are not using a compiler that understands this GCC extension.

like image 116
jxh Avatar answered Jan 13 '23 15:01

jxh


I'm not sure how you can do it "in one macro" for functions of different types, unless you opt to specify the actual return value from outside.

If you don't mind doing that, then you can take advantage of the fact that in C++ (but not in C) you can return void expressions from void functions. For example, you can return (void) 0 as a "void" value. I.e. you can do

#define CHECK_EXIT_IN_FUNC(ret)  if( exitFlag_ ) {\
    //do something\
    return (ret);\
}

and invoke it as CHECK_EXIT_IN_FUNC(false) or CHECK_EXIT_IN_FUNC((void) 0) depending on the type of the function.

like image 40
AnT Avatar answered Jan 13 '23 15:01

AnT