Macro substitution conundrum

Discussion in 'C Programming' started by Harold Weissman, Dec 13, 2007.

  1. I have a C file that contains (among other things) a number of
    macros that will be replaced depending on whether or not a compile-time
    option is defined. For example, two functions f and g in that file might
    be

    int f(void)
    {
    int x ;

    x = MY_SYMBOL ;

    return x + 3 ;
    }

    int g(void)
    {
    int y ;

    y = MY_SYMBOL ;

    return y + 4 ;
    }

    We also have, in some include file used by the C file in question,

    #ifdef COMPILE_TIME_FLAG
    #define MY_SYMBOL 1
    #else
    #define MY_SYMBOL 0
    #endif

    What I would like is for x to be assigned 1 or 0, depending on whether or
    not COMPILE_TIME_FLAG is defined, while y is to be assigned 0 no matter
    whether or not COMPILE_TIME_FLAG is defined. As you can see, this is a
    toy example that is trivially solved by other means; I am just
    illustrating a general question.

    Something I tried was

    #define NO_REPLACE

    int g(void)
    {
    int y ;

    #ifdef COMPILE_TIME_FLAG
    #ifdef NO_REPLACE
    #undef COMPILE_TIME_FLAG
    #define SET_COMPILE_TIME_FLAG
    #endif
    y = MY_SYMBOL ;
    #ifdef SET_COMPILE_TIME_FLAG
    #define COMPILE_TIME_FLAG
    #endif
    #endif

    return y + 4 ;
    }

    but it does not work (and it is ugly to boot.)

    Any ideas as to how to do this? Actually, is it doable?
    Harold Weissman, Dec 13, 2007
    #1
    1. Advertising

  2. Harold Weissman <> wrote in comp.lang.c:

    > What I would like is for x to be assigned 1 or 0, depending on whether
    > or not COMPILE_TIME_FLAG is defined, while y is to be assigned 0 no
    > matter whether or not COMPILE_TIME_FLAG is defined.



    y = 0;


    I'm gonna assume that I misunderstand the problem.

    --
    Tomás Ó hÉilidhe
    Tomás Ó hÉilidhe, Dec 13, 2007
    #2
    1. Advertising

  3. Harold Weissman

    Mark Bluemel Guest

    Harold Weissman wrote:
    > I have a C file that contains (among other things) a number of
    > macros that will be replaced depending on whether or not a compile-time
    > option is defined.


    [Snip]

    > What I would like is for x to be assigned 1 or 0, depending on whether or
    > not COMPILE_TIME_FLAG is defined, while y is to be assigned 0 no matter
    > whether or not COMPILE_TIME_FLAG is defined.


    If you've got two different types of behaviour, you need two symbols,
    IMHO.

    However, like Tomas, I don't believe I understand what you're getting
    at with this question.

    Rather than giving us the trivial version, why don't you describe what
    you are trying to _achieve_ and let us make some suggestions based on
    that?
    Mark Bluemel, Dec 13, 2007
    #3
  4. Harold Weissman

    Willem Guest

    Harold wrote:
    ) I have a C file that contains (among other things) a number of
    ) macros that will be replaced depending on whether or not a compile-time
    ) option is defined. ...
    )
    ) What I would like is for x to be assigned 1 or 0, depending on whether or
    ) not COMPILE_TIME_FLAG is defined, while y is to be assigned 0 no matter
    ) whether or not COMPILE_TIME_FLAG is defined. As you can see, this is a
    ) toy example that is trivially solved by other means; I am just
    ) illustrating a general question.

    You can #undefine a macro and then #define it again with a different value.
    Maybe that helps ?


    SaSW, Willem
    --
    Disclaimer: I am in no way responsible for any of the statements
    made in the above text. For all I know I might be
    drugged or something..
    No I'm not paranoid. You all think I'm paranoid, don't you !
    #EOT
    Willem, Dec 13, 2007
    #4
  5. On Thu, 13 Dec 2007 19:05:26 +0000, Mark Bluemel wrote:

    > Rather than giving us the trivial version, why don't you describe what
    > you are trying to _achieve_ and let us make some suggestions based on
    > that?


    My aim is to understand what it is that can and can't be done
    with the preprocessor. In this sense, one thing that would be useful is
    for somebody to explain why the approach I proposed does not work.
    Harold Weissman, Dec 13, 2007
    #5
  6. Harold Weissman

    Kaz Kylheku Guest

    On Dec 13, 11:24 am, Harold Weissman <> wrote:
    > My aim is to understand what it is that can and can't be done
    > with the preprocessor. In this sense, one thing that would be useful is
    > for somebody to explain why the approach I proposed does not work.


    The results of macro substitution are not interpreted as a
    preprocessing directive, even if they resemble one.

    I.e. you cannot use macro expansion to generate preprocessing
    directives.
    Kaz Kylheku, Dec 13, 2007
    #6
  7. Harold Weissman <> wrote:
    Mark Bluemel wrote:
    > > Rather than giving us the trivial version, why don't
    > > you describe what you are trying to _achieve_ and let
    > > us make some suggestions based on that?

    >
    > My aim is to understand what it is that can and can't be
    > done with the preprocessor.


    See Boosts preprocessor library.

    Bare in mind, despite being compatible, you won't see much
    usage of it in many C programs.

    --
    Peter
    Peter Nilsson, Dec 13, 2007
    #7
  8. On Thu, 13 Dec 2007 18:55:13 GMT, Harold Weissman
    <> wrote:

    > We also have, in some include file used by the C file in question,
    >
    > #ifdef COMPILE_TIME_FLAG
    > #define MY_SYMBOL 1
    > #else
    > #define MY_SYMBOL 0
    > #endif
    >

    This #define's MY_SYMBOL to either 1 or 0 depending on the value of
    COMPILE_TIME_FLAG *at the point of the #include*.

    > What I would like is for [one use] to be assigned 1 or 0, depending on whether or
    > not COMPILE_TIME_FLAG is defined, while y is to be assigned 0 no matter
    > whether or not COMPILE_TIME_FLAG is defined. As you can see, this is a
    > toy example that is trivially solved by other means; I am just
    > illustrating a general question.
    >
    > Something I tried was
    >
    > #define NO_REPLACE
    >
    > int g(void)
    > {
    > int y ;
    >
    > #ifdef COMPILE_TIME_FLAG
    > #ifdef NO_REPLACE
    > #undef COMPILE_TIME_FLAG
    > #define SET_COMPILE_TIME_FLAG
    > #endif
    > y = MY_SYMBOL ;
    > #ifdef SET_COMPILE_TIME_FLAG
    > #define COMPILE_TIME_FLAG
    > #endif
    > #endif
    >

    If COMPILE_TIME_FLAG is unset this leaves y uninitialized garbage; I
    hope you meant to put or leave something in the alternative. But as
    you say it doesn't accomplish what you wanted because the expansion of
    MY_SYMBOL doesn't depend on the value of COMPILE_TIME_FLAG *here*.

    > return y + 4 ;
    > }
    >
    > but it does not work (and it is ugly to boot.)
    >
    > Any ideas as to how to do this? Actually, is it doable?


    Yes, but not if you want to work for my company or sell to me.

    If you want an expression-like macro X whose evaluated value depends
    on the value of another macro Y where X is used, X must be an
    expression which uses (invokes) Y and depends on the result. Here:

    #ifdef COMPILE_TIME_FLAG
    #define MY_SYMBOL (NO_REPLACE? 0: 1)
    #else
    #define MY_SYMBOL (NO_REPLACE? 0: 0) /* or just 0 */
    #endif
    /* note parentheses around expansion needed in _most_ possible uses
    because ternary is roughly third-lowest precedence,
    and should always be provided to allow for _all_ legal uses */
    /* but DO leave space between name and ( otherwise you are
    instead trying to define a FUNCTION-like macro you don't want */
    ....
    #define NO_REPLACE 0
    y = MY_SYMBOL; /* gets 1 or 0 depending on COMPILE_TIME_FLAG */
    #undef NO_REPLACE
    #define NO_REPLACE 1
    y = MY_SYMBOL; /* gets 0 */
    #undef NO_REPLACE

    Note that NO_REPLACE must have some scalar value, preferably 1 or 0,
    wherever MY_SYMBOL is used. You might prefer to organize this as:

    .... definition as above
    #define NO_REPLACE 0 /* 'normal' case */
    ....
    y = MY_SYMBOL; /* gets depending value */
    ....
    #undef NO_REPLACE
    #define NO_REPLACE 1
    y = MY_SYMBOL; /* gets 0 */
    #undef NO_REPLACE
    #define NO_REPLACE 0
    ....
    y = MY_SYMBOL; /* depending value again */
    (The relevant subsequence seen by the preprocessor is the same, just
    the positioning in your source files is different and perhaps easier
    to keep straight if the NO_REPLACE 1 case is rare.)

    This works, but is disgustingly ugly, confusing, and fragile. If your
    design requires you to do this, better to change your design.

    If your NO_REPLACE 1 case is (or can easily be) syntactically nested
    e.g. only within a function(s), you might even do something like:

    #define MY_SYMBOL (no_replace_var? 1: otherwise)
    extern const int no_replace_var = 0; /* global setting */
    ....
    MY_SYMBOL /* expands to code that should be optimized to
    depending value -- but not a constant expression; can't safely
    be used in case labels, array bounds (except C99 auto) etc. */
    ....
    int func () {
    static const int no_replace_var = 1; /* for this function only */
    MY_SYMBOL /* expands to code that should optimize to 0 */
    }

    This is slightly less ugly and may be justifiable in a few rare cases,
    but only with VERY clear comments and documentation.

    - formerly david.thompson1 || achar(64) || worldnet.att.net
    David Thompson, Dec 24, 2007
    #8
    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. tmponko
    Replies:
    3
    Views:
    5,194
    tmponko
    Jan 1, 2004
  2. Johan

    macro substitution

    Johan, Oct 29, 2004, in forum: C++
    Replies:
    2
    Views:
    1,653
    David Harmon
    Oct 29, 2004
  3. Malcolm

    Macro Substitution Help Request

    Malcolm, Sep 8, 2005, in forum: C Programming
    Replies:
    14
    Views:
    576
    Keith Thompson
    Sep 11, 2005
  4. Chad
    Replies:
    3
    Views:
    452
    Singamsetty
    Oct 18, 2005
  5. main()

    Question on macro substitution

    main(), Sep 19, 2006, in forum: C Programming
    Replies:
    2
    Views:
    364
    Krishanu Debnath
    Sep 19, 2006
Loading...

Share This Page