Tags:
create new tag
, view all tags
There are some simple macros and some more complicated ones.

This I understand:

#define MAX 1000

When the C code is preprocessed (before it is compiled), everywhere the string MAX appears in the code it is replaced by the string 1000. It is important to realize that the macro preprocessor will simply insert the string 1000 in the code — the interpretation of that string is made by the C compiler (based on the C syntax), not by the macro preprocessor.

In the following macro, I don't understand the purpose of all the parenthesis, especially the outermost set around the replacement string — see the quote below the macro from the Xos.h header of the XFree86 source code and see XsmD20030422):

#define index(s,c) (strchr((s),(c)))

"# #define index(s,c) (strchr((s),(c))) not #defined index(s,c) strchr(s,c) somebody might be using them (which??) as function pointers??"

Continued in Notes, below.

See:

Contents

Notes

But, it looks like "Learn C Programming in 21 Days" might address this (around page 513 — reading).

It addresses at least some of the parenthesis, some are required for proper syntax of a substitution macro, in fact (paraphrasing) here are some macro syntax rules:

  • there must be no whitespace between the name of the macro and the opening parenthesis (otherwise, everything after the whitespace is treated as the macro, with very different results)
  • all macro parameters listed within the first set of parenthesis must be used in the macro expansion (otherwise something goes wrong, but I forget what — maybe the macro is just ignored?)

Then the reason for some of the macros in the expansion:

The innermost set: If s and c were not individually enclosed within parenthesis (like (s) and (c)), then if s and c were multi term thingies (like s expanded to x + 1 and c expanded to y + 1, and the macro expansion was like (s * c), you can see fairly easily see that the results with and without that set of parenthesis are significantly different. With the parenthesis you get (x + 1) * (y + 1) which results in xy + y + x + 1, without the parenthesis you get x + 1 * y + 1 which results in x + y + 1.

The middle set of parenthesis strchr((s),(c)) appears to be just what is required (in this case) to make the macro expand to a function call, i.e., strchr().

I guess it's the outer set of parenthesis (strchr((s),(c))) is the one I don't understand and may be the one referred to in the earlier quote:

"# #define index(s,c) (strchr((s),(c))) not #defined index(s,c) strchr(s,c) somebody might be using them (which??) as function pointers??"

I suppose I could take a guess at the meaning, but I think I'll try to learn more about function pointers first. Or, think on paper:

What is a function pointer? (In my own words) a function pointer is a pointer that points to a function (instead of, a piece of data or a data structure).

What does the syntax look like? Guess this is where I have to refresh my memory.

Some resources that might be useful re the above question about function pointers (found by a Google search on [macro c replacement function]:

Ok, I'm not sure I've found the answer on the function pointers, but the last resource above explains why parenthesis are required in several places, and provides this set of rules:

To summarize the important rules of this section, whenever defining a function-like macro, remember:

  1. Put parentheses around each instance of each macro parameter in the replacement text.
  2. Put parentheses around the entire replacement text.
  3. Capitalize the macro name to remind yourself that it is a macro, so that you won't call it on arguments with side effects.

Remember, too, not to put a space between the macro name and the open parenthesis in the definition.

A few final notes about function-like preprocessor macros: Sometimes, people try to write function-like macros which are even more like functions in that they expand to multiple statements; however, this is considerably trickier than it looks (at least, if it's not to fall victim to additional sets of pitfalls). Also, people sometimes wish for macros that take a variable number of arguments (in much the same way that the printf function accepts a variable number of arguments), but there's not yet a good way to do this, either.

And, I'm not sure it's covered in the summary above, but they also warn you about the non-determinability of a macro that includes the increment or decrement operator — i++ or similar.

PS: It looks like those class notes might be a very good resource for C in general — I'll have to browse through them some more.

And, I might have to reorder —s I may be running low. wink

Contributors

  • () RandyKramer - 23 Apr 2003
  • If you edit this page: add your name here; move this to the next line; and if you've used a comment marker (your initials in parenthesis), include it before your WikiName.

Page Ratings

Edit | Attach | Watch | Print version | History: r3 < r2 < r1 | Backlinks | Raw View | Raw edit | More topic actions
Topic revision: r3 - 2003-04-25 - RandyKramer
 
  • Learn about TWiki  
  • Download TWiki
This site is powered by the TWiki collaboration platform Powered by PerlCopyright 1999-2017 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding WikiLearn? WebBottomBar">Send feedback
See TWiki's New Look