preprocessor trick

Discussion in 'C Programming' started by Lola, Feb 10, 2011.

  1. Lola

    Lola Guest

    Hi,

    I am trying the folowing preprocessor trick with gcc but it doesn't
    seem to work (worked with all the compilers I have used so far):

    #ifdef GLOBAL_VARS
    #define EXT
    #define EQ =
    #else
    #define EXT extern
    #define EQ ;##/##/
    #endif

    I get the error:

    In file included from src/verilog.cpp:16:
    ../include/verilog.h:35:1: pasting ";" and "/" does not give a valid
    preprocessing token
    ../include/verilog.h:35:1: pasting "/" and "/" does not give a valid
    preprocessing token
    In file included from src/verilog.cpp:16:
    ../include/verilog.h:35: error: expected unqualified-id before '/'
    token

    any ideas?
    lola
    Lola, Feb 10, 2011
    #1
    1. Advertising

  2. Lola <> writes:

    > I am trying the folowing preprocessor trick with gcc but it doesn't
    > seem to work (worked with all the compilers I have used so far):


    As a general rule, I am wary of anything that can be called a
    "preprocessor trick". Often, the effect is to obfuscate the code so you
    need to be sure that they pay their way, so to speak.

    > #ifdef GLOBAL_VARS
    > #define EXT
    > #define EQ =
    > #else
    > #define EXT extern
    > #define EQ ;##/##/
    > #endif
    >
    > I get the error:
    >
    > In file included from src/verilog.cpp:16:


    From the file name it looks like you may be using C++. You should know
    that there are differences between the two preprocessors and this may
    matter. In fact, the way I'd do what I think you are trying to do
    relies on one of these differences.

    > ./include/verilog.h:35:1: pasting ";" and "/" does not give a valid
    > preprocessing token


    The error message is accurate. Presumably you know what ## does in a
    macro body -- it joins two tokens into one -- and the message is
    reporting that ;/ is not a valid token in C. I'd guess the first ## is
    simply not meant to be there.

    > ./include/verilog.h:35:1: pasting "/" and "/" does not give a valid
    > preprocessing token


    This one, though accurate, is not so helpful. Comments are treated as
    white space so // is not, in fact, a valid preprocessing token. What's
    more (and this affects the whole intent of your "trick") comments are
    removed before macros are expanded. The effect of this is that a macro
    can't expand to a comment which seems to be what your trick is trying to
    do.

    > In file included from src/verilog.cpp:16:
    > ./include/verilog.h:35: error: expected unqualified-id before '/'
    > token


    This is just the compiler ploughing on and not making sense of what the
    erroneous macros have left behind.

    gcc is quite correct to reject the code. What compilers accepted it?

    Something like this:

    #ifdef GLOBAL_VARS
    #define EXT
    #define INIT(...) = __VA_ARGS__
    #else
    #define EXT extern
    #define INIT(...)
    #endif

    /* e.g. */
    EXT int x INIT(42);
    EXT int x[] INIT({1, 2, 3});

    might suit but since the source would need to be re-written I'd probably
    go for in GLOBAL macro:

    #ifdef GLOBAL_VARS
    #define GLOBAL(n, ...) n = __VA_ARGS__
    #else
    #define GLOBAL(n, ...) extern n
    #endif

    /* e.g. */
    GLOBAL(int x, 42);
    GLOBAL(int x[], {1,2,3});

    The motivation seems to be based on having a large number of external
    variables that you want to be able to define and to declare using just
    one source. There may well be some other way to organise the code that
    avoids the problem in the first place but it hard to know without seeing
    the use to put these macros to.

    --
    Ben.
    Ben Bacarisse, Feb 10, 2011
    #2
    1. Advertising

  3. Lola

    Lola Guest

    On Feb 10, 12:24 pm, Ben Bacarisse <> wrote:
    > Lola <> writes:
    > > I am trying the folowing preprocessor trick with gcc but it doesn't
    > > seem to work (worked with all the compilers I have used so far):

    >
    > As a general rule, I am wary of anything that can be called a
    > "preprocessor trick".  Often, the effect is to obfuscate the code so you
    > need to be sure that they pay their way, so to speak.
    >
    > > #ifdef GLOBAL_VARS
    > >   #define EXT
    > >   #define EQ  =
    > > #else
    > >   #define EXT extern
    > >   #define EQ  ;##/##/
    > > #endif

    >
    > > I get the error:

    >
    > > In file included from src/verilog.cpp:16:

    >
    > From the file name it looks like you may be using C++.  You should know
    > that there are differences between the two preprocessors and this may
    > matter.  In fact, the way I'd do what I think you are trying to do
    > relies on one of these differences.
    >
    > > ./include/verilog.h:35:1: pasting ";" and "/" does not give a valid
    > > preprocessing token

    >
    > The error message is accurate.  Presumably you know what ## does in a
    > macro body -- it joins two tokens into one -- and the message is
    > reporting that ;/ is not a valid token in C.  I'd guess the first ## is
    > simply not meant to be there.
    >
    > > ./include/verilog.h:35:1: pasting "/" and "/" does not give a valid
    > > preprocessing token

    >
    > This one, though accurate, is not so helpful.  Comments are treated as
    > white space so // is not, in fact, a valid preprocessing token.  What's
    > more (and this affects the whole intent of your "trick") comments are
    > removed before macros are expanded.  The effect of this is that a macro
    > can't expand to a comment which seems to be what your trick is trying to
    > do.
    >
    > > In file included from src/verilog.cpp:16:
    > > ./include/verilog.h:35: error: expected unqualified-id before '/'
    > > token

    >
    > This is just the compiler ploughing on and not making sense of what the
    > erroneous macros have left behind.
    >
    > gcc is quite correct to reject the code.  What compilers accepted it?
    >


    thanks for the prompt responce... It is a new program which I am about
    to start and was just exorcising the best practice to use in it.. I'll
    try the one below...

    The compilers I have used with it so far are: VC++, armcc, and Zilog.
    In embedded systems and the used of globals is done more often for
    various reason.


    > Something like this:
    >
    >   #ifdef GLOBAL_VARS
    >     #define EXT
    >     #define INIT(...)  = __VA_ARGS__
    >   #else
    >     #define EXT extern
    >     #define INIT(...)
    >   #endif
    >
    >   /* e.g. */
    >   EXT int x INIT(42);
    >   EXT int x[] INIT({1, 2, 3});
    >
    > might suit but since the source would need to be re-written I'd probably
    > go for in GLOBAL macro:
    >
    >   #ifdef GLOBAL_VARS
    >     #define GLOBAL(n, ...) n = __VA_ARGS__
    >   #else
    >     #define GLOBAL(n, ...) extern n
    >   #endif
    >
    >   /* e.g. */
    >   GLOBAL(int x, 42);
    >   GLOBAL(int x[], {1,2,3});
    >
    > The motivation seems to be based on having a large number of external
    > variables that you want to be able to define and to declare using just
    > one source.  There may well be some other way to organise the code that
    > avoids the problem in the first place but it hard to know without seeing
    > the use to put these macros to.
    >
    > --
    > Ben.
    Lola, Feb 10, 2011
    #3
  4. Lola

    Seebs Guest

    On 2011-02-10, Lola <> wrote:
    > I am trying the folowing preprocessor trick with gcc but it doesn't
    > seem to work (worked with all the compilers I have used so far):


    Blind luck.

    > #else
    > #define EXT extern
    > #define EQ ;##/##/


    This is not valid. ## has to yield a single preprocessing token.

    Some compilers will, by blind luck, ignore this -- because they're just
    ramming the text together and hoping for the best.

    -s
    --
    Copyright 2010, all wrongs reversed. Peter Seebach /
    http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
    http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
    I am not speaking for my employer, although they do rent some of my opinions.
    Seebs, Feb 11, 2011
    #4
  5. Lola

    Thad Smith Guest

    On 2/10/2011 4:10 AM, Lola wrote:
    > Hi,
    >
    > I am trying the folowing preprocessor trick with gcc but it doesn't
    > seem to work (worked with all the compilers I have used so far):
    >
    > #ifdef GLOBAL_VARS
    > #define EXT
    > #define EQ =
    > #else
    > #define EXT extern
    > #define EQ ;##/##/
    > #endif


    Here is a way that you can define and conditionally initialize a global variable
    with C90 (Ben has shown a better way with C99):

    #ifdef GLOBAL_VARS
    #define GLOBAL
    #else
    #define GLOBAL extern
    #endif

    GLOBAL int foo[5]
    #ifdef GLOBAL_VARS
    = {1,2,3,4,5}
    #endif
    ;

    --
    Thad
    Thad Smith, Feb 12, 2011
    #5
    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. Nuri Yilmaz

    A .Net trick everyday!

    Nuri Yilmaz, Jul 28, 2004, in forum: ASP .Net
    Replies:
    0
    Views:
    390
    Nuri Yilmaz
    Jul 28, 2004
  2. Nuri YILMAZ

    A .Net trick everday!

    Nuri YILMAZ, Aug 9, 2004, in forum: ASP .Net
    Replies:
    0
    Views:
    425
    Nuri YILMAZ
    Aug 9, 2004
  3. Cronus
    Replies:
    1
    Views:
    643
    Paul Mensonides
    Jul 15, 2004
  4. SerGioGio

    Preprocessor trick?

    SerGioGio, Jan 22, 2005, in forum: C++
    Replies:
    9
    Views:
    2,813
    Thomas Matthews
    Jan 22, 2005
  5. Preprocessor trick

    , Nov 22, 2006, in forum: C++
    Replies:
    6
    Views:
    490
    Pete Becker
    Nov 23, 2006
Loading...

Share This Page