Node:Macro functions, Previous:Macros, Up:Macros



Macro functions

Macros can also accept parameters and return values. Macros that do so are called macro functions. To create a macro function, simply define a macro with a parameter that has whatever name you like, such as my_val. For example, one macro defined in the standard libraries is abs, which returns the absolute value of its parameter. Let us define our own version, ABS, below. (Note that we are defining it in upper case not only to avoid conflicting with abs, but also because all macros should be defined in upper case, in the GNU coding style. See Style.)

#define ABS(my_val) ((my_val) < 0) ? -(my_val) : (my_val)

This macro uses the ?...:... command to return a positive number no matter what value is assigned to my_val -- if my_val is defined as a positive number, the macro returns the same number, and if my_val is defined as a negative number, the macro returns its negative (which will be positive). (See Decisions, for more information on the ?...:... structure. If you write ABS(-4), then the preprocessor will substitute -4 for my_val; if you write ABS(i), then the preprocessor will substitute i for my_val, and so on. Macros can take more than one parameter, as in the code example below.

One caveat: macros are substituted whole wherever they are used in a program: this is potentially a huge amount of code repetition. The advantage of a macro over an actual function, however, is speed. No time is taken up in passing control to a new function, because control never leaves the home function; the macro just makes the function a bit longer.

A second caveat: function calls cannot be used as macro parameters. The following code will not work:

ABS (cos(36))

Here is an example of macro functions in use:

#include <stdio.h>

#define STRING1          "A macro definition\n"
#define STRING2          "must be all on one line!\n"
#define EXPRESSION1      1 + 2 + 3 + 4
#define EXPRESSION2      EXPRESSION1 + 10
#define ABS(x)           ((x) < 0) ? -(x) : (x)
#define MAX(a,b)         (a < b) ?  (b) : (a)
#define BIGGEST(a,b,c)   (MAX(a,b) < c) ?  (c) : (MAX(a,b))

int main ()
{
  printf (STRING1);
  printf (STRING2);
  printf ("%d\n", EXPRESSION1);
  printf ("%d\n", EXPRESSION2);
  printf ("%d\n", ABS(-5));
  printf ("Biggest of 1, 2, and 3 is %d\n", BIGGEST(1,2,3));

  return 0;
}

The output from the code example above is as follows:

A macro definition
must be all on one line!
10
20
5
Biggest of 1, 2, and 3 is 3