Both the tokens combined by could come from the macro

Info icon This preview shows pages 22–25. Sign up to view the full content.

View Full Document Right Arrow Icon
Both the tokens combined by ‘ ## ’ could come from the macro body, but you could just as well write them as one token in the first place. Token pasting is most useful when one or both of the tokens comes from a macro argument. If either of the tokens next to an ‘ ## is a parameter name, it is replaced by its actual argument before ‘ ## ’ executes. As with stringification, the actual argument is not macro-expanded first. If the argument is empty, that ‘ ## ’ has no effect. Keep in mind that the C preprocessor converts comments to whitespace before macros are even considered. Therefore, you cannot create a comment by concatenating ‘ / ’ and * ’. You can put as much whitespace between ‘ ## ’ and its operands as you like, including comments, and you can put comments in arguments that will be concatenated. However, it is an error if ‘ ## ’ appears at either end of a macro body.
Image of page 22

Info icon This preview has intentionally blurred sections. Sign up to view the full version.

View Full Document Right Arrow Icon
Chapter 3: Macros 19 Consider a C program that interprets named commands. There probably needs to be a table of commands, perhaps an array of structures declared as follows: struct command { char *name; void (*function) (void); }; struct command commands[] = { { "quit", quit_command }, { "help", help_command }, ... }; It would be cleaner not to have to give each command name twice, once in the string constant and once in the function name. A macro which takes the name of a command as an argument can make this unnecessary. The string constant can be created with stringi- fication, and the function name by concatenating the argument with ‘ _command ’. Here is how it is done: #define COMMAND(NAME) { #NAME, NAME ## _command } struct command commands[] = { COMMAND (quit), COMMAND (help), ... }; 3.6 Variadic Macros A macro can be declared to accept a variable number of arguments much as a function can. The syntax for defining the macro is similar to that of a function. Here is an example: #define eprintf(...) fprintf (stderr, __VA_ARGS__) This kind of macro is called variadic . When the macro is invoked, all the tokens in its argument list after the last named argument (this macro has none), including any commas, become the variable argument . This sequence of tokens replaces the identifier __VA_ARGS__ in the macro body wherever it appears. Thus, we have this expansion: eprintf ("%s:%d: ", input_file, lineno) 7→ fprintf (stderr, "%s:%d: ", input_file, lineno) The variable argument is completely macro-expanded before it is inserted into the macro expansion, just like an ordinary argument. You may use the ‘ # ’ and ‘ ## ’ operators to stringify the variable argument or to paste its leading or trailing token with another token. (But see below for an important special case for ‘ ## ’.) If your macro is complicated, you may want a more descriptive name for the variable argument than __VA_ARGS__ . CPP permits this, as an extension. You may write an argu- ment name immediately before the ‘ ... ’; that name is used for the variable argument. The eprintf macro above could be written #define eprintf(args...) fprintf (stderr, args) using this extension. You cannot use __VA_ARGS__ and this extension in the same macro.
Image of page 23
Chapter 3: Macros 20 You can have named arguments as well as variable arguments in a variadic macro. We
Image of page 24

Info icon This preview has intentionally blurred sections. Sign up to view the full version.

View Full Document Right Arrow Icon
Image of page 25
This is the end of the preview. Sign up to access the rest of the document.

{[ snackBarMessage ]}

What students are saying

  • Left Quote Icon

    As a current student on this bumpy collegiate pathway, I stumbled upon Course Hero, where I can find study resources for nearly all my courses, get online help from tutors 24/7, and even share my old projects, papers, and lecture notes with other students.

    Student Picture

    Kiran Temple University Fox School of Business ‘17, Course Hero Intern

  • Left Quote Icon

    I cannot even describe how much Course Hero helped me this summer. It’s truly become something I can always rely on and help me. In the end, I was not only able to survive summer classes, but I was able to thrive thanks to Course Hero.

    Student Picture

    Dana University of Pennsylvania ‘17, Course Hero Intern

  • Left Quote Icon

    The ability to access any university’s resources through Course Hero proved invaluable in my case. I was behind on Tulane coursework and actually used UCLA’s materials to help me move forward and get everything together on time.

    Student Picture

    Jill Tulane University ‘16, Course Hero Intern