What does the # operator do before a parameter in the definition of a macro?

Asked

Viewed 54 times

3

One of the possible macro definitions assert(), as I found in Mingw’s code,.

#define assert(_Expression) \
 (void) \
 ((!!(_Expression)) || \
  (_assert(#_Expression,__FILE__,__LINE__),0))

I don’t understand what the excerpt #_Expression in the fourth line makes. How it works?

2 answers

3


It is a preprocessing operator formally known as "Stringification Operator" or "Stringfication Operator".

It is used in the body of a macro for the purpose of informing the preprocessor that the macro parameter must be converted into a string.

Basically, the preprocessor will put the macro parameter in double quotes after being replaced in the macro body.

Follow a practical example as a demonstration:

#include <stdio.h>

#define debug_ptr(x)     printf("%s => %p\n", #x, x )
#define debug_int(x)     printf("%s => %d\n", #x, x )
#define debug_bool(x)    printf("%s => %s\n", #x, (x) ? "TRUE" : "FALSE" )

int foobar(int x)
{
    return x * 2;
}

int main(void)
{
    int a = 123;
    int b = 321;

    debug_ptr(&a);
    debug_int(b);
    debug_bool(a > b);
    debug_int(foobar(a));

    return 0;
}

After the pre-processing step, code macros would be expanded to something like:

#include <stdio.h>

int foobar(int x)
{
    return x * 2;
}

int main(void)
{
    int a = 123;
    int b = 321;

    printf("%s => %p\n", "&a", &a )
    printf("%s => %d\n", "b", b )
    printf("%s => %s\n", "a > b", (a > b) ? "TRUE" : "FALSE" )
    printf("%s => %d\n", "foobar(a)", foobar(a) )

    return 0;
}

Exit:

&a => 0x7ffee3284a98
b => 321
a > b => FALSE
foobar(a) => 246

2

He’s a kind of toString() of macro. He takes that content and turns it into a string, so he quotes there on that expression.

So let’s say that you call the (macro) function of the question like this:

assert(x == 0);

After preprocessing the code will look something like this:

(void)((!!(x == 0)) || (_assert("x == 0", __FILE__, __LINE__), 0))

This way there in function _assert() can be used with the exact message of the expression you used in the code to print or log in some information.

Documentation.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.