Do function like macros need a mandatory parenthes

2019-07-14 19:44发布

问题:

Here is what confuses me:

To define a function-like macro, you use the same '#define' directive, but you put a pair of parentheses immediately after the macro name.

I believe this is to make the code stand out for people other than the author of the program. Like other rules of CAPS for macro names. But the following is where I get confused:

A function-like macro is only expanded if its name appears with a pair of parentheses after it. If you write just the name, it is left alone.

I disagreed instantly after reading it. And gcc -E verified that in the following code

#define FUNC display()

void display()
  {
    printf("Display\n");
  }

int main()
  {
    FUNC;
    return 0;
   }

The pre-processed output shows the content of the main() function as expected:

int main()
  {
    display();
    return 0;
  }

So what am I missing here? The pre-processor is for tokenizing the source, the macro expansion is a token and the above code was processed that way, the pre-processor isn't supposed to check anything or verify anything, it just dumps tokens. In that case what is the gcc manual trying to convey.

I am learning C programming, so I might be misunderstanding it a great deal as it frequently happens, I searched for a proper explanation and finally resorted to asking here. Please help me with this.

回答1:

When you define:

#define FUNC display()

FUNC is not a function-like macro; it is an object-like macro that expands to a function call.

A function-like macro looks like:

#define FUNC() display()

Now you must write FUNC() to invoke it. Or, more frequently, it will have arguments:

#define MIN(x, y) ((x) > (y) ? (x) : (y))

and that can be invoked with:

int min = MIN(sin(p), cos(q));

with cautions about the number of times the arguments are expanded.

See also getc() as macro and C standard library function definition. It includes the standard's explanation of why it is important that the simple name of a function-like macro without a following open parenthesis is not expanded, which is what the quote from the GCC manual is telling you.

When a function-like macro is defined, the open parenthesis must 'touch' the macro name:

#define function_like(a) …
#define object_like (…)

Because there's a space after object_like, the open parenthesis is part of the replacement text, not the start of an argument list. When the function-like macro is invoked, there may be spaces between the macro name and the argument list:

function_like (x)    // Valid invocation of function_like macro.

However, if you wrote:

int (function_like)(double a) { return asin(a) + 2 * atanh(a); }

this is not an invocation of the function-like macro because the token after function_like is not an open parenthesis.



回答2:

There are two kinds of macros. They differ mostly in what they look like when they are used.
Object-like macros resemble data objects when used, function-like macros resemble function calls.

You may define any valid identifier as a macro, even if it is a C keyword. The preprocessor does not know anything about keywords. This can be useful if you wish to hide a keyword such as const from an older compiler that does not understand it. However, the preprocessor operator can never be defined as a macro, and C++'s named operators cannot be macros when you are compiling C++.