function-like macro versus macros

2020-04-16 06:24发布

问题:

gcc (GCC) 4.7.2
c89

Hello,

I have been looking at a test suite and I noticed this function-like macro declared like this:

#define MU_SUITE_START() char *msg = NULL

However, is there any real difference to doing just this instead:

#define MU_SUITE_START char *msg = NULL

Macros just do text replacement so I don't think there is going to be any performance issues.

Using cpp I get the following results so nothing special here.

function-like macro

char *msg = __null;

marco

char *msg = __null;

Just a side note: Is it worth declaring a function-like marco that doesn't provide in input parameters? Here I am not passing any parameters i.e.

#define PRINT_MSG() printf("This is the message\n")

Why bother with the function-like macro if there are no input parameters, isn't this better?

#define PRINT_MSG printf("This is the message\n")

Many thanks for any suggestions,

回答1:

There's one difference between the object-like and function-like macros:

#define OBJECT     char *msg1 = NULL
#define FUNCTION() char *msg2 = NULL

void somefunc(void)
{
    int OBJECT = 5;
    int FUNCTION = 10;
    ...
}

The declaration for OBJECT is replaced by the macro (so the code won't compile), but the reference to FUNCTION is not a macro invocation because it is not followed by an open parenthesis.

This is seldom important. However, when it is, it really matters.

A more typical case might be a function that can be implemented as a macro. For sake of discussion (because it is easily understood rather than because it is a good example):

extern int isdigit(int c);
#define isdigit(c) ((c) >= '0' && (c) <= '9')

and in an implementation file:

int (isdigit)(int c)
{
    assert((c >= 0 && c <= UCHAR_MAX) || c == EOF);
    return isdigit(c);
}

Ignoring little details like that isn't how isdigit() is likely to be implemented, and a macro implementation of isdigit() is not allowed to evaluate its argument more than once, and you aren't supposed to redefine things that are in the standard C library, the function definition is not macro expanded because the name isdigit is not followed by (, but the macro inside the function is expanded. At least the function is implemented in terms of the macro, which pretty much guarantees the same behaviour.



标签: c macros