0

In particular, I'm trying to find a reference document for the accepted answer to this question: Macro and function with same name

Can anyone point to any good references for parenthesis use in functions declarations as shown in the aforementioned example?

Any references on syntax tips/tricks in C would be appreciated too!

Community
  • 1
  • 1
kavehv
  • 3
  • 2
  • 4
    You can read the C language standard. It should be available online. – Kerrek SB Sep 16 '13 at 16:46
  • I take it you are referring to: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf I can't really find an example of what I'm looking for in that document. – kavehv Sep 16 '13 at 16:50
  • [N1570](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf) is more current; it's a recent draft of the C11 standard, whereas N1256 is an updated draft of C99. – Keith Thompson Sep 16 '13 at 17:20

1 Answers1

3

You are referencing a correct document in your comment (the C99 standard, http://open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf, the newer C11 standard does not introduce any significant changes to these sections). The sections that deal with macro replacements are 6.10.3 and 6.10.3.4. In particular, the mechanism that makes infinite replacement loops impossible (which is the core of the mechanism described in the link you mentioned) is found in 6.10.3.4(2):

If the name of the macro being replaced is found during this scan of the replacement list (not including the rest of the source file’s preprocessing tokens), it is not replaced. Furthermore, if any nested replacements encounter the name of the macro being replaced, it is not replaced. These nonreplaced macro name preprocessing tokens are no longer available for further replacement even if they are later (re)examined in contexts in which that macro name preprocessing token would otherwise have been replaced.`

This part of 6.10.3(10) deals with the instances when the macro name is not expanded:

Each subsequent instance of the function-like macro name followed by a ( as the next preprocessing token introduces the sequence of preprocessing tokens that is replaced by the replacement list in the definition (an invocation of the macro).`

Note the 'followed by a (' bit. This implies (since the standard does not specify otherwise) that in the absence of a '(' the macro is not expanded and is interpreted as a C token.

A great resource for 'deciphering' some arcane aspects of the C standard is The New C Standard: An Economic and Cultural Commentary available at http://www.knosof.co.uk/cbook/cbook.html. A fair warning: it is a long book but well worth reading if one is into the arcana of C. It does not deal with macros though. A lighter reading is C: A Reference Manual (check out http://careferencemanual.com/) which does have a chapter on the subtleties of the C preprocessor.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
alexsh
  • 1,121
  • 8
  • 12
  • That addresses the recursion aspect of macro replacement, but what section describes how wrapping a function in parentheses will prevent the preprocessor from replacing the function name with the definition of a macro for that text? – kavehv Sep 16 '13 at 17:21
  • I still don't quite understand how this maps to the case for 'int (myfunc)(int a, int b)' not expanding 'myfunc' if it has been defined previously as a macro. – kavehv Sep 16 '13 at 18:34
  • `myfunc` was defined as a *function-like macro* which, according to 6.10.3(10) will be expanded *if* followed by an opening parenthesis. In the case of `(myfunc)` it is not followed by an opening parenthesis, so (since the standard does not say anything about macro expansion in such cases), macro expansion is not done and the token `myfunc` is passed on unexpanded. The declaration of `myfunc` is not affected by the presence of parentheses. – alexsh Sep 16 '13 at 20:42
  • Here is a different way of stopping the macro expansion, not mentioned in the link you referenced, perhaps it will make things a bit clearer: `#define NOEXPAND #define myfunc(a,b) a + b int myfunc NOEXPAND (int x, int y){ return myfunc( x, y ); /* this will be expanded*/ } /* outer myfunc not expanded */` (to experiment with this, format it appropriately). Note that `NOEXPAND` is not a parenthesis but it itself expands to nothing. – alexsh Sep 16 '13 at 21:02
  • Also, may I suggest you reword your question to something like 'How does C99 (or C11) standard apply to explain this case of macro expansion.' to make it sound less generic. – alexsh Sep 16 '13 at 21:13
  • I'm not sure about 'implies'; the standard states that an invocation of a function-like macro must consist of the macro name followed by an open parenthesis (once comments have been removed, etc). If the character after the macro name is not an open parenthesis, therefore, it is not an invocation of the (function-like) macro. Hence the `int (myfunc)(int a, int b)` sequence is explicitly not an invocation of the macro `#define myfunc(a, b) myfunc(do_a(a), do_b(b))`, as in the x-ref'd question. – Jonathan Leffler Sep 17 '13 at 21:20
  • Indeed, this is a rather sloppy wording on my part. Perhaps 'as a consequence, ... in the absence of ...' would have been a bit better (short of getting into full 'language-lawyer' details)? – alexsh Sep 17 '13 at 21:45