Node:Macros, Next:, Previous:A few directives, Up:Preprocessor directives



Macros

Macros can make long, ungainly pieces of code into short words. The simplest use of macros is to give constant values meaningful names. For example:

#define MY_PHONE 5551234

This allows the programmer to use the word MY_PHONE to mean the number 5551234. In this case, the word is longer than the number, but it is more meaningful and makes a program read more naturally. It can also be centralised in a header file, where it is easily changed; this eliminates tedious search-and-replace procedures on code if the value appears frequently in the code. It has been said, with some humorous exaggeration, that the only values that should appear "naked" in C code instead of as macros or variables are 1 and 0.

The difference between defining a macro for 5551234 called MY_PHONE and declaring a long integer variable called my_phone with the same value is that the variable my_phone has the value 5551234 only provisionally; it can be incremented with the statement my_phone++;, for example. In some sense, however, the macro MY_PHONE is that value, and only that value -- the C preprocessor simply searches through the C code before it is compiled and replaces every instance of MY_PHONE with 5551234. Issuing the command MY_PHONE++; is no more or less sensible than issuing the command 5551234++;.

Any piece of C code can be made into a macro, Macros are not merely constants referred to at compile time, but are strings that are physically replaced with their values by the preprocessor before compilation. For example:

#define SUM 1 + 2 + 3 + 4

would allow SUM to be used instead of 1 + 2 + 3 + 4. Usually, this would equal 10, so that in the statement example1 = SUM + 10;, the variable example1 equals 20. Sometimes, though, this macro will be evaluated differently; for instance, in the statement example2 = SUM * 10;, the variable example2 equals 46, instead of 100, as you might think. Can you figure out why? Hint: it has to do with the order of operations.

The quotation marks in the following macro allow the string to be called by the identifier SONG instead of typing it out over and over. Because the text 99 bottles of beer on the wall... is enclosed by double quotation marks, it will never be interpreted as C code.

#define SONG "99 bottles of beer on the wall..."

Macros cannot define more than a single line, but they can be used anywhere except inside strings. (Anything enclosed in string quotes is assumed to be untouchable by the compiler.)

Some macros are defined already in the file stdio.h, for example, NULL (the value 0).

There are a few more directives for macro definition besides #define:


#undef
This undefines a macro, leaving the name free.
#ifdef
This is a kind of #if that is followed by a macro name. If that macro is defined then this directive is true. #ifdef works with #else in the same way that #if does.
#ifndef
This is the opposite of #ifdef. It is also followed by a macro name. If that name is not defined then this is true. It also works with #else.

Here is a code example using some macro definition directives from this section, and some conditional compilation directives from the last section as well.

#include <stdio.h>

#define CHOICE 500

int my_int = 0;

#undef CHOICE
#ifdef CHOICE
void set_my_int()
{
  my_int = 23;
}
#else
void set_my_int()
{
  my_int = 17;
}
#endif

int main ()
{
  set_my_int();
  printf("%d\n", my_int);

  return 0;
}

The above code example displays 17 on the screen.