Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Macro substitution conundrum

Reply
Thread Tools

Macro substitution conundrum

 
 
Harold Weissman
Guest
Posts: n/a
 
      12-13-2007
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?

 
Reply With Quote
 
 
 
 
Tomás Ó hÉilidhe
Guest
Posts: n/a
 
      12-13-2007
Harold Weissman <(E-Mail Removed)> 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
 
Reply With Quote
 
 
 
 
Mark Bluemel
Guest
Posts: n/a
 
      12-13-2007
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?
 
Reply With Quote
 
Willem
Guest
Posts: n/a
 
      12-13-2007
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
 
Reply With Quote
 
Harold Weissman
Guest
Posts: n/a
 
      12-13-2007
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.

 
Reply With Quote
 
Kaz Kylheku
Guest
Posts: n/a
 
      12-13-2007
On Dec 13, 11:24 am, Harold Weissman <(E-Mail Removed)> 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.
 
Reply With Quote
 
Peter Nilsson
Guest
Posts: n/a
 
      12-13-2007
Harold Weissman <(E-Mail Removed)> 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
 
Reply With Quote
 
David Thompson
Guest
Posts: n/a
 
      12-24-2007
On Thu, 13 Dec 2007 18:55:13 GMT, Harold Weissman
<(E-Mail Removed)> 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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Macro substitution and runtime question. Chad C Programming 3 10-18-2005 01:37 AM
Macro Substitution Help Request Malcolm C Programming 14 09-11-2005 07:43 PM
macro substitution Johan C++ 2 10-29-2004 04:14 PM
Makefile Macro Substitution Help tmponko C++ 3 01-01-2004 12:57 AM
Converted to Mozilla but one thing missing - key macro/substitution no-spam Firefox 5 07-29-2003 08:07 PM



Advertisments