Macro Expansion

Discussion in 'C Programming' started by Vittal, Mar 22, 2005.

  1. Vittal

    Vittal Guest

    Hello All,

    I am trying to get a cut down version of preprocessor output. Let me
    make myself clear with a sample:
    ***************************************************************************
    /*file x.c */
    #include <stdio.h>

    int main ()
    {
    int i = 10;
    #ifdef TEST
    i = i +10;
    #else
    i = i -10;
    #endif
    printf("The value of i = %d \n",i);
    }

    *************************************************************************
    If I take the preprocessor output for the above file, the output file
    will contain huge amount of code as the contents of all the header
    files are dumped into output code.

    What I am looking at is a output of this nature (if TEST is not
    defined)
    *********************************************************************
    #include <stdio.h>

    int main ()
    {
    int i = 10;
    i = i -10;
    printf("The value of i = %d \n",i);
    }
    *********************************************************************

    Is it possible to get a output of this nature. Is there any way I can
    ask the preprocessor not to dump the header file contents, or is there
    any other tool available which can serve this purpose?

    Any help in this regard is greatly appreciated.

    Thanks
    -Vittal
     
    Vittal, Mar 22, 2005
    #1
    1. Advertising

  2. Vittal

    Eric Sosman Guest

    Vittal wrote:
    > Hello All,
    >
    > I am trying to get a cut down version of preprocessor output. [...]


    This is Question 10.18 in the comp.lang.c Frequently
    Asked Questions (FAQ) list

    http://www.eskimo.com/~scs/C-faq/top.html

    --
     
    Eric Sosman, Mar 22, 2005
    #2
    1. Advertising

  3. On 22 Mar 2005 07:13:11 -0800, Vittal
    <> wrote:

    > I am trying to get a cut down version of preprocessor output. Let me
    > make myself clear with a sample:
    > ***************************************************************************
    > /*file x.c */
    > #include <stdio.h>
    >
    > int main ()
    > {
    > int i = 10;
    > #ifdef TEST
    > i = i +10;
    > #else
    > i = i -10;
    > #endif
    > printf("The value of i = %d \n",i);
    > }
    >
    > *************************************************************************
    > If I take the preprocessor output for the above file, the output file
    > will contain huge amount of code as the contents of all the header
    > files are dumped into output code.
    >
    > What I am looking at is a output of this nature (if TEST is not
    > defined)
    > *********************************************************************
    > #include <stdio.h>
    >
    > int main ()
    > {
    > int i = 10;
    > i = i -10;
    > printf("The value of i = %d \n",i);
    > }
    > *********************************************************************
    >
    > Is it possible to get a output of this nature. Is there any way I can
    > ask the preprocessor not to dump the header file contents, or is there
    > any other tool available which can serve this purpose?


    It will be specific to the preprocessor (indeed the C standard doesn't
    mandate that the preprocessor stage be able to produce any output at
    all, it could keep it all in memory for instance). Some preprocessors
    do things like putting the line number at the start of each line, or
    inserting #line directives or other oddities.

    Since yours is fairly 'clean', though, the easiest way to do it is to
    put some marker after the #include files:

    #include <stdio.h>

    /* LOAD oF RuBbIsH which WON't aPPear aNyWherE ELSE */

    and then post-process the resulting file and cut out everything before
    the marker line. On a *ix system I'd use sed, for example:

    gcc -E x.c | sed '1,/LOAD oF RuBbIsH which WON't aPPear aNyWherE ELSE/d'

    If your preprocessor inserts lines like

    #line 123 "stdio.h"

    then you could write a more intelligent post-processor (I'd use Perl or
    AWK) which keeps track of which file produced the output and only output
    that belonging to the top-level source. For instance, gcc (version 3.3.5)
    produces output like:

    # 1 "x.c"
    # 1 "<built-in>"
    # 1 "<command line>"
    # 1 "x.c"

    char x;

    # 1 "1.h" 1

    char x1;
    # 1 "11.h" 1
    char x11;
    # 4 "1.h" 2
    # 1 "12.h" 1
    char x12;
    # 5 "1.h" 2
    char x1_end;
    # 5 "x.c" 2
    # 1 "2.h" 1

    char x2;
    # 1 "21.h" 1
    char x21;
    # 4 "2.h" 2
    # 1 "22.h" 1
    char x22;
    # 5 "2.h" 2
    char x2_end;
    # 6 "x.c" 2

    char x_end;

    (Sorry, I wasn't very inventive with the file or variable names!)

    With system includes it puts more digits on the end of the # lines, I
    have no idea what they mean. Anyway, you can see that by recognising
    the string with the source file name and only doing output when the last
    string matches the top file name you could extract only the code you
    want...

    Chris C
     
    Chris Croughton, Mar 22, 2005
    #3
  4. Vittal

    Eric Sosman Guest

    Chris Croughton wrote:
    > On 22 Mar 2005 07:13:11 -0800, Vittal wrote:
    >
    >>I am trying to get a cut down version of preprocessor output. [...]

    > [...]
    > Since yours is fairly 'clean', though, the easiest way to do it is to
    > put some marker after the #include files:
    >
    > #include <stdio.h>
    >
    > /* LOAD oF RuBbIsH which WON't aPPear aNyWherE ELSE */
    >
    > and then post-process the resulting file and cut out everything before
    > the marker line. [...]


    If the implementation makes the preprocessor's "output"
    available (not guaranteed, as you note), the original comments
    are not likely to be present in it. Comments disappear in
    translation phase 3, before preprocessing directives and macro
    expansions are processed. A better marker would be something
    you're sure will survive past phase 4, like

    char *delete_thru_here = "LoAd Of rUbBiSh";

    There's still a problem, though, and it's a pretty bad
    one. Even though this technique lets you snip away everything
    the headers injected before the marker, the effects of any
    macros defined in those headers will still appear in the
    preprocessed source that follows. On one compiler I happen
    to have handy,

    #include <stdio.h>
    int main(void) {
    fputs ("Hello, world!\n", stderr);
    return 0;
    }

    becomes (after preprocessing and snipping)

    int main(void) {
    fputs ("Hello, world!\n", (&__dj_stderr));
    return 0;
    }

    Observe that the portable identifier `stderr' has been
    replaced by a non-portable expression -- it happens to be
    correct for the system at hand, but this transformed source
    is no longer portable. Similar problems can be expected
    with any other header-defined macros: INT_MAX, setjmp, ERANGE,
    offsetof, ... In fact, all standard library functions are
    subject to this sort of mangling, since the implementation is
    permitted to define "masking" macros for them.

    The compiler's job is to transform portable (we hope)
    source code into a non-portable construct specialized for one
    implementation. The preprocessor performs part of that
    specialization, and its output has usually lost a good deal
    of the portability the original source may have had. This
    makes the "run it through the preprocessor and then fool
    around with the output" strategy problematic at best.

    --
    Eric Sosman
    lid
     
    Eric Sosman, Mar 23, 2005
    #4
    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,140
    Victor Bazarov
    Nov 9, 2004
  2. Benjamin Niemann
    Replies:
    3
    Views:
    341
    Caleb Hattingh
    Aug 26, 2004
  3. Ark

    A question on macro expansion

    Ark, Jul 22, 2004, in forum: C Programming
    Replies:
    3
    Views:
    370
  4. Dom Gilligan

    Macro expansion of '#__LINE__'?

    Dom Gilligan, Nov 4, 2005, in forum: C Programming
    Replies:
    4
    Views:
    465
    Dom Gilligan
    Nov 4, 2005
  5. reppisch

    partial/selective Macro expansion scpp

    reppisch, May 5, 2006, in forum: C Programming
    Replies:
    7
    Views:
    380
    michi
    May 7, 2006
Loading...

Share This Page