During preprocessing, all "macro names" that appear in the program are replaced with the strings in the macro definition. This is called "macro substitution" or "macro substitution" Macro Expand". Macro definition is completed by the macro definition command in the source program. Macro substitution is done automatically by the preprocessor. If the string is an expression, we call it a functional macro definition.
Let’s take the following two lines of code as an example to expand the description:
Functional macro definition: #define MAX(a,b) ((a)>(b)? (a):(b))
Ordinary function: MAX(a,b) { return a>b?a:b;}
( 1) The parameters defined by functional macros have no type. The preprocessor is only responsible for formal replacement and does not perform parameter type checking, so be extra careful when passing parameters.
(2) Pay attention to the format when defining functional macros, especially the parentheses.
If the above macro definition function is written as #define MAX(a,b) (a>b?a:b) and omits the inner brackets, the running result will be wrong due to the operator priority after macro expansion; If the above macro definition function omits the outer parentheses and the macro definition is MAX(a,b), then the macro expansion becomes (a)>(b)?(a):(b), and the operation priority is also wrong.
(3) If the function parameter is an expression, the replacement process of ordinary function calling and functional macro definition is different.
When a normal function is called, the value of the actual parameter expression is first obtained and then passed to the formal parameter. If the actual parameter expression has a Side Effect, then these Side Effects only occur once. For example, MAX(a, b), if MAX is an ordinary function, a and b are only increased once. But if MAX functional macro is defined, it needs to be expanded to k = (( a)>( b)?( a):( b)), and a and b are not necessarily increased once or twice. Therefore, if the parameter is an expression, you must be careful when replacing the functional macro definition.
(4) The instructions generated by compiling the code that calls the real function and the code that calls the functional macro definition are different.
If MAX is an ordinary function, then its function body return a > b ? a : b; must be compiled to generate instructions. Each call that appears in the code must also be compiled to generate parameter passing instructions and call instructions. And if MAX is a functional macro definition, the macro definition itself does not need to be compiled to generate instructions, but the instructions generated by compilation for each call that appear in the code are equivalent to a function body, rather than simply a few parameter passing instructions and call instructions. . Therefore, the target file generated by compilation using functional macro definition will be larger.
Advantages:
First of all, function calling will bring additional overhead. It needs to open up a stack space, record the return address, push the formal parameters onto the stack, and release the stack when returning from the function. This overhead will reduce code efficiency, and using macro definitions is better than functions in terms of code size and speed;
Secondly, the parameters of the function must be declared as a specific type, so it can only When used in expressions of appropriate types, if we want to compare the sizes of two floating point types, we have to write a comparison function specifically for floating point types. On the contrary, the above macro definition can be used for integers, long Integers, single floating-point types, double floating-point types, and other types whose values can be compared using the "<" operator, that is, macros have nothing to do with types.
The above is the detailed content of Macro definition function. For more information, please follow other related articles on the PHP Chinese website!