macro expansion

Discussion in 'C Programming' started by borophyll@gmail.com, Aug 23, 2007.

  1. Guest

    Yet another macro question....

    I am trying to ascertain a deterministic algorithm for processing
    macro expansions. From my experimentation on GCC, it seems that macro
    expansion is performed in roughly the following way:

    1. When preprocessor comes across a macro name, it replaces name with
    definition, and substitutes all formal parameters with the supplied
    arguments

    2. For each argument, perform macro expansion (if any). If the
    result is further macros with arguments, then recursively process
    these arguments.

    3. Once we have descended as far as recursion can take us, we
    backtrack to the previous macro that we expanded, and rescan it for
    further expansion. We repeatedly backtrack until we have reached the
    start

    Here is an example

    #define VERSION 6
    #define str(x) #x
    #define xstr(x) str(x)
    #define INCFILE2(x) vers##x.h
    #define INCFILE(x) INCFILE2(x)


    #include xstr(INCFILE(VERSION))

    The preprocessor sees the macro xstr, so it replaces it with its
    definition

    --> str(INCFILE(VERSION))

    The preprocessor then performs further macro expansion on all
    arguments. There is only one argument, INCFILE(VERSION), which we can
    expand to

    --> str(INCFILE2(VERSION))

    This argument also happens to be a macro with parameters, so we
    descend further. It has only one argument, VERSION, which is expanded

    --> str(INCFILE2(6))

    We have descended as deep as we can go, so we now back up and rescan
    what we have produced, which is INCFILE2(6). This can be further
    expanded, as INCFILE2 happens to be a macro. We do so...

    --> str(vers##6.h)

    The ## operator simplifies this to

    --> str(vers6.h)

    We have simplified this as far as possible, so we now backtrack again
    and rescan. The preprocessor recognises str as a macro, and it
    expands it

    --> #vers6.h

    which finally produces

    "vers6.h"

    We have backtracked all the way to the start, so the macro has been
    fully expanded.

    Is this correct? Comments welcome...

    Regards, B
     
    , Aug 23, 2007
    #1
    1. Advertising

  2. On 23 août, 05:00, wrote:
    > Yet another macro question....
    >
    > I am trying to ascertain a deterministic algorithm for processing
    > macro expansions. From my experimentation on GCC, it seems that macro
    > expansion is performed in roughly the following way:
    >
    > 1. When preprocessor comes across a macro name, it replaces name with
    > definition, and substitutes all formal parameters with the supplied
    > arguments
    >
    > 2. For each argument, perform macro expansion (if any). If the
    > result is further macros with arguments, then recursively process
    > these arguments.
    >
    > 3. Once we have descended as far as recursion can take us, we
    > backtrack to the previous macro that we expanded, and rescan it for
    > further expansion. We repeatedly backtrack until we have reached the
    > start
    >
    > Here is an example
    >
    > #define VERSION 6
    > #define str(x) #x
    > #define xstr(x) str(x)
    > #define INCFILE2(x) vers##x.h
    > #define INCFILE(x) INCFILE2(x)
    >
    > #include xstr(INCFILE(VERSION))
    >
    > The preprocessor sees the macro xstr, so it replaces it with its
    > definition
    >
    > --> str(INCFILE(VERSION))
    >
    > The preprocessor then performs further macro expansion on all
    > arguments. There is only one argument, INCFILE(VERSION), which we can
    > expand to
    >
    > --> str(INCFILE2(VERSION))
    >
    > This argument also happens to be a macro with parameters, so we
    > descend further. It has only one argument, VERSION, which is expanded
    >
    > --> str(INCFILE2(6))
    >
    > We have descended as deep as we can go, so we now back up and rescan
    > what we have produced, which is INCFILE2(6). This can be further
    > expanded, as INCFILE2 happens to be a macro. We do so...
    >
    > --> str(vers##6.h)
    >
    > The ## operator simplifies this to
    >
    > --> str(vers6.h)
    >
    > We have simplified this as far as possible, so we now backtrack again
    > and rescan. The preprocessor recognises str as a macro, and it
    > expands it
    >
    > --> #vers6.h
    >
    > which finally produces
    >
    > "vers6.h"
    >
    > We have backtracked all the way to the start, so the macro has been
    > fully expanded.
    >
    > Is this correct? Comments welcome...
    >
    > Regards, B


    Yes, but it is not enough to explain the complete behavior of the
    preprocessor and its possibilities. Paul Mensonides wrote a nice
    documentation of about 20 pages on this topic (the most complete I
    know). If you are really interested by cpp, you could ask him for a
    copy and look into the code of the cpp library chaos-pp:

    http://chaos-pp.cvs.sourceforge.net/chaos-pp/chaos-pp/

    You can also have a look to fpp (much smaller):

    http://cos.cvs.sourceforge.net/cos/COS/src/cos/fpp/

    fpp doesn't use "slicing contexts" (interleaved invocations) for
    simplicity (and maybe better portability), but it only targets code
    generation by manipulating tuples, while chaos-pp target a complete
    computational model and provides various data structures and
    algorithms.

    a+, ld.
     
    Laurent Deniau, Aug 23, 2007
    #2
    1. Advertising

  3. Guest

    On Aug 23, 5:59 pm, Laurent Deniau <> wrote:
    > On 23 août, 05:00, wrote:
    >
    >
    >
    > > Yet another macro question....

    >
    > > I am trying to ascertain a deterministic algorithm for processing
    > > macro expansions. From my experimentation on GCC, it seems that macro
    > > expansion is performed in roughly the following way:

    >
    > > 1. When preprocessor comes across a macro name, it replaces name with
    > > definition, and substitutes all formal parameters with the supplied
    > > arguments

    >
    > > 2. For each argument, perform macro expansion (if any). If the
    > > result is further macros with arguments, then recursively process
    > > these arguments.

    >
    > > 3. Once we have descended as far as recursion can take us, we
    > > backtrack to the previous macro that we expanded, and rescan it for
    > > further expansion. We repeatedly backtrack until we have reached the
    > > start

    >
    > > Here is an example

    >
    > > #define VERSION 6
    > > #define str(x) #x
    > > #define xstr(x) str(x)
    > > #define INCFILE2(x) vers##x.h
    > > #define INCFILE(x) INCFILE2(x)

    >
    > > #include xstr(INCFILE(VERSION))

    >
    > > The preprocessor sees the macro xstr, so it replaces it with its
    > > definition

    >
    > > --> str(INCFILE(VERSION))

    >
    > > The preprocessor then performs further macro expansion on all
    > > arguments. There is only one argument, INCFILE(VERSION), which we can
    > > expand to

    >
    > > --> str(INCFILE2(VERSION))

    >
    > > This argument also happens to be a macro with parameters, so we
    > > descend further. It has only one argument, VERSION, which is expanded

    >
    > > --> str(INCFILE2(6))

    >
    > > We have descended as deep as we can go, so we now back up and rescan
    > > what we have produced, which is INCFILE2(6). This can be further
    > > expanded, as INCFILE2 happens to be a macro. We do so...

    >
    > > --> str(vers##6.h)

    >
    > > The ## operator simplifies this to

    >
    > > --> str(vers6.h)

    >
    > > We have simplified this as far as possible, so we now backtrack again
    > > and rescan. The preprocessor recognises str as a macro, and it
    > > expands it

    >
    > > --> #vers6.h

    >
    > > which finally produces

    >
    > > "vers6.h"

    >
    > > We have backtracked all the way to the start, so the macro has been
    > > fully expanded.

    >
    > > Is this correct? Comments welcome...

    >
    > > Regards, B

    >
    > Yes, but it is not enough to explain the complete behavior of the
    > preprocessor and its possibilities. Paul Mensonides wrote a nice
    > documentation of about 20 pages on this topic (the most complete I
    > know). If you are really interested by cpp, you could ask him for a
    > copy and look into the code of the cpp library chaos-pp:
    >
    > http://chaos-pp.cvs.sourceforge.net/chaos-pp/chaos-pp/
    >
    > You can also have a look to fpp (much smaller):
    >
    > http://cos.cvs.sourceforge.net/cos/COS/src/cos/fpp/
    >
    > fpp doesn't use "slicing contexts" (interleaved invocations) for
    > simplicity (and maybe better portability), but it only targets code
    > generation by manipulating tuples, while chaos-pp target a complete
    > computational model and provides various data structures and
    > algorithms.
    >
    > a+, ld.


    It looks interesting, but I don't know how to process all that XML
    stuff that the documentation seems to be in...
     
    , Aug 23, 2007
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. me
    Replies:
    1
    Views:
    1,146
    Victor Bazarov
    Nov 9, 2004
  2. Benjamin Niemann
    Replies:
    3
    Views:
    344
    Caleb Hattingh
    Aug 26, 2004
  3. Ark

    A question on macro expansion

    Ark, Jul 22, 2004, in forum: C Programming
    Replies:
    3
    Views:
    379
  4. Vittal

    Macro Expansion

    Vittal, Mar 22, 2005, in forum: C Programming
    Replies:
    3
    Views:
    428
    Eric Sosman
    Mar 23, 2005
  5. Dom Gilligan

    Macro expansion of '#__LINE__'?

    Dom Gilligan, Nov 4, 2005, in forum: C Programming
    Replies:
    4
    Views:
    468
    Dom Gilligan
    Nov 4, 2005
Loading...

Share This Page