What are some tricks I can use with macros? [close

2019-01-16 01:59发布

In our legacy code, as well as our modern code, we use macros to perform nifty solutions like code generations, etc. And we make use of both the # and ## operators.

I am curious how other developers use macros to do cool things, if they use them at all.

25条回答
混吃等死
2楼-- · 2019-01-16 02:42

The BOOST_BINARY macro performs some clevel pre-processor trickery to give C++ the ability to express numeric constants in binary. It is limited to 0-255 however.

查看更多
再贱就再见
3楼-- · 2019-01-16 02:43

One can simplify repetitive things for ie. enum lists

enum {
  kOneEnum,
  kTwoEnum,
  kThreeEnum,
  kFourEnum
};

...and later do a switch case over a structured way

#define TEST( _v ) \
    case k ## _v ## Enum: \
      CallFunction ## _v(); \
      break;

switch (c) {
    TEST( One   );
    TEST( Two   );
    TEST( Three );
    TEST( Four  );
}

Note: Sure this could be done with a function pointer array but this opens for a little more flexibilities to add parameters and also use the string expansions with the single hash.

...or to test on strings to get the right enum value

int value = -1;
char *str = getstr();

#define TEST( _v ) \
    if (!strcmp(# _v, str)) \
        value = k ## _v ## Enum

TEST( One   );
TEST( Two   );
TEST( Three );
TEST( Four  );
查看更多
beautiful°
4楼-- · 2019-01-16 02:44

Most (all?) C++ Unit Testing frameworks are built upon macros. We use UnitTest++. Check it out to see all sorts of fancy macros.

查看更多
啃猪蹄的小仙女
5楼-- · 2019-01-16 02:46

Converting them to a construct of the language to improve type safety and debugging ability.

查看更多
Rolldiameter
6楼-- · 2019-01-16 02:46

One of my favorite tricks is a way to pass variable number of arguments to macros, to be later used in calling printf-like functions for example. To do this, I specify that the macro has only one parameter and use it in the body of the macro without (), but pass all the parameters to the macro in (( and )), so the list looks like a single argument. For example,

#define TRACE( allargs) do { printf allargs; } while ( 0)
...
TRACE(( "%s %s\n", "Help", "me"));
查看更多
Deceive 欺骗
7楼-- · 2019-01-16 02:49

In C, it's common to define macros that do some stuff getting the verbatim argument, and at the same time define functions to be able to get the address of it transparently.

// could evaluate at compile time if __builtin_sin gets
// special treatment by the compiler
#define sin(x) __builtin_sin(x)

// parentheses avoid substitution by the macro
double (sin)(double arg) {
    return sin(arg); // uses the macro
}

int main() {
    // uses the macro
    printf("%f\n", sin(3.14));

    // uses the function
    double (*x)(double) = &sin;

    // uses the function
    printf("%f\n", (sin)(3.14));
}
查看更多
登录 后发表回答