Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Macro expansion for macros with arguments vs. variables with the same name

Consider the following C program (ignore the double side-effect issue):

#define max(a, b) (a>b?a:b)

int main(void){
    int max = max(5,6);
    return max;
}

The GCC preprocessor turns this into:

int main(void){
    int max = (5>6?5:6);
    return max;
}

Which is quite nice, since you don't have to worry about unintentional collisions between max and max(). The GCC manual says:

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

Is this standardized or just something done by convention?

like image 693
mensi Avatar asked Jun 11 '12 16:06

mensi


People also ask

What is the correct way to name a macro with two arguments?

To use a macro that expects arguments, you write the name of the macro followed by a list of actual arguments in parentheses, separated by commas. The number of actual arguments you give must match the number of arguments the macro expects. Examples of use of the macro min include min (1, 2) and min (x + 28, *p).

What is macro explain macro with arguments?

Macro Arguments (DEFINE-! ENDDEFINE command) The macro definition can include macro arguments, which can be assigned specific values in the macro call. There are two types of arguments: keyword and positional. Keyword arguments are assigned names in the macro definition; in the macro call, they are identified by name.

What is expansion variable in macro?

A macro variable is expanded “in place” to yield a text string that may then be expanded further. This distinction will become more clear as we proceed. A variable name can contain almost any characters including most punctuation. Even spaces are allowed, but if you value your sanity you should avoid them.

How can you pass arguments to a macro?

Passing parameters to a macro. A parameter can be either a simple string or a quoted string. It can be passed by using the standard method of putting variables into shared and profile pools (use VPUT in dialogs and VGET in initial macros).


1 Answers

Yes, the behavior here is well-defined.

Your macro max is a function-like macro (i.e., when you define it, its name is followed immediately by a left parenthesis and it takes arguments).

A use of max later in your code is only an invocation of that macro if the use of max is followed by a left parenthesis. So, these would not invoke the max macro:

int max;
max = 42;

But these would all invoke the max macro:

max(1, 2)
max (1, 2)
max
(
    1, 2
)
max()

(Note that the last line is ill-formed because the number of arguments does not match the number of parameters. This is still a macro invocation, though, and would cause a compilation error.)

This behavior is mandated by the C langauge standard. C99 §6.10.3/10 states that after a function-like macro has been defined,

Each subsequent instance of the function-like macro name followed by a ( as the next preprocessing token introduces the sequence of preprocessing tokens that is replaced by the replacement list in the definition (an invocation of the macro).

like image 79
James McNellis Avatar answered Sep 23 '22 13:09

James McNellis