Velocity Reviews > Macro with a default value

# Macro with a default value

aleksa
Guest
Posts: n/a

 11-14-2010
I would like to have a "dofor" macro which would use
either a suplied loop variable or a default loop variable (f).

dofor(512, i) // should be expanded to
for (i = 512; i != 0; i--)

dofor(512) // should be expanded to
for (f = 512; f != 0; f--)

Could someone give me some pointers here?

Tom St Denis
Guest
Posts: n/a

 11-14-2010
On Nov 14, 6:08*am, "aleksa" <(E-Mail Removed)> wrote:
> I would like to have a "dofor" macro which would use
> either a suplied loop variable or a default loop variable (f).
>
> dofor(512, i) // should be expanded to
> for (i = 512; i != 0; i--)
>
> dofor(512) // should be expanded to
> for (f = 512; f != 0; f--)
>
> Could someone give me some pointers here?

Good preprocessor question, but I'd like to just step in here and say:
"Don't write code like this."

Replacing single statements with macros is a surefire way to make your
code completely unmaintainable. Don't do it if you have any hope of
working on it long term.

Tom

Stefan Ram
Guest
Posts: n/a

 11-14-2010
"aleksa" <(E-Mail Removed)> writes:
>dofor(512, i) // should be expanded to
>for (i = 512; i != 0; i--)
>dofor(512) // should be expanded to
>for (f = 512; f != 0; f--)

I does not work as follows,
but maybe someone can improve on this?

#define test(x) \
0/x/2; printf( "%s\n", #x ); if( 0 )\
+printf( "f\n" );

The idea is that with »test(i)«, this expands to

0/i/2; printf( "%s\n", "i" ); if( 0 )
+printf( "f\n" );

i.e., effectively,

printf( "%s\n", "i" );

, which should print the line »i«, while »test()«
expands to

0//2; printf( "%s\n", "i" ); if( 0 )
+printf( "f\n" );

, effectively,

0+printf( "f\n" );

, which should print the line »f«. However, it seems
that the »/« do not form a single »//« token this way.

Eric Sosman
Guest
Posts: n/a

 11-14-2010
On 11/14/2010 7:39 AM, Stefan Ram wrote:
> "aleksa"<(E-Mail Removed)> writes:
>> dofor(512, i) // should be expanded to
>> for (i = 512; i != 0; i--)
>> dofor(512) // should be expanded to
>> for (f = 512; f != 0; f--)

>
> I does not work as follows,
> but maybe someone can improve on this?
>
> #define test(x) \
> 0/x/2; printf( "%s\n", #x ); if( 0 )\
> +printf( "f\n" );
>
> The idea is that with »test(i)«, this expands to
>
> 0/i/2; printf( "%s\n", "i" ); if( 0 )
> +printf( "f\n" );
>
> i.e., effectively,
>
> printf( "%s\n", "i" );
>
> , which should print the line »i«, while »test()«
> expands to
>
> 0//2; printf( "%s\n", "i" ); if( 0 )
> +printf( "f\n" );
>
> , effectively,
>
> 0+printf( "f\n" );
>
> , which should print the line »f«. However, it seems
> that the »/« do not form a single »//« token this way.

Right, because comments are recognized and removed in phase 3,
before the preprocessor does its work in phase 4. See section 5.1.1.2
"Translation phases."

--
Eric Sosman
http://www.velocityreviews.com/forums/(E-Mail Removed)lid

Seebs
Guest
Posts: n/a

 11-14-2010
On 2010-11-14, aleksa <(E-Mail Removed)> wrote:
> I would like to have a "dofor" macro which would use
> either a suplied loop variable or a default loop variable (f).
>
> dofor(512, i) // should be expanded to
> for (i = 512; i != 0; i--)
>
> dofor(512) // should be expanded to
> for (f = 512; f != 0; f--)
>
> Could someone give me some pointers here?

You can't do optional-argument macros.

Furthermore, don't do this. Several reasons, not the least of which is
that you're counting backwards which will usually surprise people, and
you should never hide simple basic syntax behind macros.

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / (E-Mail Removed)
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.

Keith Thompson
Guest
Posts: n/a

 11-14-2010
Seebs <(E-Mail Removed)> writes:
> On 2010-11-14, aleksa <(E-Mail Removed)> wrote:
>> I would like to have a "dofor" macro which would use
>> either a suplied loop variable or a default loop variable (f).
>>
>> dofor(512, i) // should be expanded to
>> for (i = 512; i != 0; i--)
>>
>> dofor(512) // should be expanded to
>> for (f = 512; f != 0; f--)
>>
>> Could someone give me some pointers here?

>
> You can't do optional-argument macros.
>
> Furthermore, don't do this. Several reasons, not the least of which is
> that you're counting backwards which will usually surprise people, and
> you should never hide simple basic syntax behind macros.

C99 added variadic macros. You *might* be able to do something like:

#define dofor(count, ...) /* something */

so at least both dofor(512, i) and dofor(512) would be legal. But I
can't think of a way to make this work for what the OP is asking about
(not that I tried very hard).

To the OP: If you're going to do this, at least use all-caps for the
macro name. (The convention of using all-caps for macro names is
intended to make them stand out, so it's obvious to the reader that
something strange is going on.)

For that matter, there's not that much benefit in using a single name
for both. If you want the loop variable name to default to i (yours
defaults to f, but i makes more sense), you could just write:

#define DOFOR(count, var) for ((var) = (count); (var) != 0; (var)--)
#define DOFORI(count) for (i = (count); i != 0; i--)

Or, if you can depend on having a C99 compiler, or at least one that
supports declarations in for loops as an extension:

#define DOFOR(count, var) for (int var = (count); (var) != 0; (var)--)
#define DOFORI(count) for (int i = (count); i != 0; i--)

You have to know how many arguments you're using when you write the
call; using distinct names isn't much of an added burden.

But these are all improvements on a bad idea. A better solution is
just to write ordinary for loops; they're going to be much more
from now).

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"