Go Back   Velocity Reviews > Newsgroups > C Programming
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

Reply

C Programming - preprocessor arithmetic

 
Thread Tools Search this Thread
Old 10-29-2009, 01:20 PM   #31
Default Re: preprocessor arithmetic


Eric Sosman <> writes:
>Andrey Vul wrote:
>>[...]
>>Think of what I'm trying to do as factorial via preprocessor (i.e. the
>>expansion of f(5) would be (5*(4*(3*(2*(1))))) ,but how do you tail
>>decrement and recurse properly?

>You don't.


You google.

http://google.to/search?q=factorial+preprocessor



Stefan Ram
  Reply With Quote
Old 10-29-2009, 08:24 PM   #32
Stefan Ram
 
Posts: n/a
Default Re: preprocessor arithmetic
Eric Sosman <> writes:
>>http://google.to/search?q=factorial+preprocessor

>I suspect you intended the first of them, but it's not C.


http://bannalia.blogspot.com/2008/10...recursion.html

is C and shows how to implement tail recursion,
which is sufficient to implement the factorial,
but not arbitrary (non-tail) recursion.

Yes, it uses boost, but the preprocessor part of
boost should be the same for C and C++.

The solution shown there will run only for small
argument values under many implementations.

My solution would be:

#define FACTORIAL0 1
#define FACTORIAL1 1
#define FACTORIAL2 2
#define FACTORIAL3 6
#define FACTORIAL4 24
#define FACTORIAL5 120
#define FACTORIAL6 720
#define FACTORIAL7 5040
#define FACTORIAL8 40320
#define FACTORIAL9 362880
#define FACTORIAL10 3628800
#define FACTORIAL11 39916800
#define FACTORIAL12 479001600
#define FACTORIAL13 6227020800
#define FACTORIAL14 87178291200
#define FACTORIAL15 1307674368000
#define FACTORIAL16 20922789888000
#define FACTORIAL17 355687428096000
#define FACTORIAL18 6402373705728000
#define FACTORIAL19 121645100408832000
#define FACTORIAL20 2432902008176640000
#define FACTORIAL21 51090942171709440000
#define FACTORIAL22 1124000727777607680000
#define FACTORIAL23 25852016738884976640000
#define FACTORIAL24 620448401733239439360000
#define FACTORIAL25 15511210043330985984000000
#define FACTORIAL26 403291461126605635584000000
#define FACTORIAL27 10888869450418352160768000000
#define FACTORIAL28 304888344611713860501504000000
#define FACTORIAL29 8841761993739701954543616000000
#define FACTORIAL30 265252859812191058636308480000000
#define FACTORIAL(x) FACTORIAL##x



Stefan Ram
  Reply With Quote
Old 10-29-2009, 09:18 PM   #33
Chris M. Thomasson
 
Posts: n/a
Default Re: preprocessor arithmetic
"Stefan Ram" <> wrote in message
news:factorial-...
> Eric Sosman <> writes:
>>>http://google.to/search?q=factorial+preprocessor

>>I suspect you intended the first of them, but it's not C.

>
> http://bannalia.blogspot.com/2008/10...recursion.html
>
> is C and shows how to implement tail recursion,
> which is sufficient to implement the factorial,
> but not arbitrary (non-tail) recursion.
>
> Yes, it uses boost, but the preprocessor part of
> boost should be the same for C and C++.
>
> The solution shown there will run only for small
> argument values under many implementations.
>
> My solution would be:

[...]
> #define FACTORIAL(x) FACTORIAL##x


FWIW, this does not work when x is a token:
__________________________________________________ _____
int
main(void)
{
#define N 4

printf("%lu\n", FACTORIAL(N));

return 0;
}
__________________________________________________ _____




You need an extra level of expansion:


#define CONCATX(t1, t2)t1##t2
#define CONCAT(t1, t2)CONCATX(t1, t2)

#define FACTORIAL(x) CONCAT(FACTORIAL, x)



Chris M. Thomasson
  Reply With Quote
Old 10-29-2009, 10:14 PM   #34
John Bode
 
Posts: n/a
Default Re: preprocessor arithmetic
On Oct 28, 4:45*pm, Andrey Vul <andrey....@gmail.com> wrote:
> Is there a way to do this:
> cat << "EOF" | cpp -Dn=2 -
> #define d define
> d foo#(n-1) (n-1)
> EOF
>
> with the output being
> #define foo1 1
>
> ?


No.

Ignoring the problems with the macro definition itself, the
preprocessor doesn't evaluate arithmetic expressions like that.
Assuming that the # operator worked like that (it doesn't), the result
would look more like

#define foo(2-1) (2-1)

The preprocessor does text substitution. Period. It doesn't
understand expressions or arithmetic or anything like that.


John Bode
  Reply With Quote
Old 10-29-2009, 10:28 PM   #35
Keith Thompson
 
Posts: n/a
Default Re: preprocessor arithmetic
John Bode <> writes:
> On Oct 28, 4:45Â*pm, Andrey Vul <andrey....@gmail.com> wrote:
>> Is there a way to do this:
>> cat << "EOF" | cpp -Dn=2 -
>> #define d define
>> d foo#(n-1) (n-1)
>> EOF
>>
>> with the output being
>> #define foo1 1
>>
>> ?

>
> No.
>
> Ignoring the problems with the macro definition itself, the
> preprocessor doesn't evaluate arithmetic expressions like that.
> Assuming that the # operator worked like that (it doesn't), the result
> would look more like
>
> #define foo(2-1) (2-1)
>
> The preprocessor does text substitution. Period. It doesn't
> understand expressions or arithmetic or anything like that.


It doesn't understand arithmetic expressions in macro expansions,
which is what the OP would need. It does understand them in #if
directives.

For example, this program:

#include <stdio.h>
int main(void)
{
#if 2 + 2 == 4
puts("ok");
#endif
#if 2 + 2 == 5
puts("OOPS");
#endif
return 0;
}

prints "ok".

--
Keith Thompson (The_Other_Keith) kst- <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"


Keith Thompson
  Reply With Quote
Old 11-02-2009, 09:03 PM   #36
Richard Bos
 
Posts: n/a
Default Re: preprocessor arithmetic
Andrey Vul <> wrote:

> On Oct 28, 10:42=A0pm, Eric Sosman <esos...@ieee-dot-org.invalid> wrote:
> > Andrey Vul wrote:

>
> > > I'm asking if there's a way to force cpp to _not_ linklist #define
> > > chains.

> >
> > =A0 =A0 =A0Yes: Just use it as it stands; there are no chains or lists
> > of definitions. =A0See 6.10.3.4.

>
> Multi-pass somehow registers with me as linked lists. My bad.
> But 6.10.3.4 is what I'm trying to subvert.


Well, _don't_. It's the wrong thing to want. It's not what the C
preprocessor was designed for, and trying to subvert that is like trying
to make a car go directly sideways: it's not normally possible, and even
when, with a great deal of dirty hackery, you manage to do it anyway in
one specific instance, you'll still end up with the steering wheel in
the wrong place and the car wider than the lane.

Richard


Richard Bos
  Reply With Quote
Old 11-03-2009, 06:35 AM   #37
Andrey Vul
 
Posts: n/a
Default Re: preprocessor arithmetic
On Oct 28, 10:41*pm, Seebs <usenet-nos...@seebs.net> wrote:
> On 2009-10-29, Andrey Vul <andrey....@gmail.com> wrote:
>
>
> > #define I #ifndef
> > #define D #define
> > #define E #endif

>
> Don't do this.


I'm using that in order to prevent premature #ifndef evaluation.


Andrey Vul
  Reply With Quote
Old 11-03-2009, 07:53 AM   #38
Seebs
 
Posts: n/a
Default Re: preprocessor arithmetic
On 2009-11-03, Andrey Vul <> wrote:
> On Oct 28, 10:41*pm, Seebs <usenet-nos...@seebs.net> wrote:
>> On 2009-10-29, Andrey Vul <andrey....@gmail.com> wrote:


>> > #define I #ifndef
>> > #define D #define
>> > #define E #endif


>> Don't do this.


> I'm using that in order to prevent premature #ifndef evaluation.


That is not how cpp works. Even if it were, it would not be a sane way
to try to do this.

If you find yourself trying to outsmart the preprocessor, stop. Go
do something else -- say, write a program to generate the code you want.

-s
--
Copyright 2009, all wrongs reversed. Peter Seebach / usenet-
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!


Seebs
  Reply With Quote
Old 11-03-2009, 01:48 PM   #39
Eric Sosman
 
Posts: n/a
Default Re: preprocessor arithmetic
Andrey Vul wrote:
> On Oct 28, 10:41 pm, Seebs <usenet-nos...@seebs.net> wrote:
>> On 2009-10-29, Andrey Vul <andrey....@gmail.com> wrote:
>>
>>
>>> #define I #ifndef
>>> #define D #define
>>> #define E #endif

>> Don't do this.

>
> I'm using that in order to prevent premature #ifndef evaluation.


No, you're using it to cause syntax errors. (Not entirely
true: You can avoid syntax errors by defining the macros as
shown and then never expanding any of them ...)

For example, if you try to use the D macro like this:

D FOO bar

you will get an expansion that might be represented as

# define FOO bar

but this expansion will *not* be a preprocessor directive. Macro
replacement never generates a preprocessor directive, even if it
generates a sequence that resembles one (6.10.3.4p3). So what
you've got is the four tokens #,define,FOO,bar surviving *after*
the preprocessor has finished its work, and that sequence of
tokens does not match any part of any production of C's grammar.
(Trivial proof: # can be a preprocessing token, but it cannot be
a token.) Hence, you get a syntax error.

You could "use" your macros in `#ifdef D' and `#ifndef I'
and `#if defined(E)' and so on, but that's all. Expand any of
them, and you're toast. Heed Seebs' advice.

--
Eric Sosman
lid


Eric Sosman
  Reply With Quote
Old 11-03-2009, 02:56 PM   #40
Andrey Vul
 
Posts: n/a
Default Re: preprocessor arithmetic
On Nov 3, 8:48*am, Eric Sosman <esos...@ieee-dot-org.invalid> wrote:
> * * *For example, if you try to use the D macro like this:
>
> * * * * D FOO bar
>
> you will get an expansion that might be represented as
>
> * * * * # define FOO bar
>
> but this expansion will *not* be a preprocessor directive. *Macro
> replacement never generates a preprocessor directive.


I know that. But cpp foo.c -DD=#define | cpp will give the intended
result.
The magic token is shell-piping what looks like a directive into an
actual directive.


Andrey Vul
  Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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

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




SEO by vBSEO 3.3.2 ©2009, Crawlability, Inc.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46