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-28-2009, 09:45 PM   #1
Default preprocessor arithmetic


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

?


Andrey Vul
  Reply With Quote
Old 10-28-2009, 09:55 PM   #2
Seebs
 
Posts: n/a
Default Re: preprocessor arithmetic
On 2009-10-28, Andrey Vul <> 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.

But you could easily do this with pure shell, or m4, or even a C program
which prints C code as its output.

-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 10-28-2009, 09:59 PM   #3
Andrey Vul
 
Posts: n/a
Default Re: preprocessor arithmetic
On Oct 28, 5:55*pm, Seebs <usenet-nos...@seebs.net> wrote:
> On 2009-10-28, 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.

Is this because cpp only does arithmetic comparison/expansion inside
#if ( ... ) ?

> But you could easily do this with pure shell, or m4, or even a C program
> which prints C code as its output.

Like this:
$(CC) -E foo.c -Dn=x -Dn_=$((x-1))
?



Andrey Vul
  Reply With Quote
Old 10-28-2009, 10:48 PM   #4
Chris M. Thomasson
 
Posts: n/a
Default Re: preprocessor arithmetic
"Andrey Vul" <> wrote in message
news:b58d10a4-36d7-4dc8-9104-...
> 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


Check this crap out:
__________________________________________________ ________
#include <stdio.h>


#define QUOTEX(t)#t
#define QUOTE(t)QUOTEX(t)


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


#define PLACEX(t)t
#define PLACE(t)PLACEX(t)


#define SELECT1(t1, t2)t1
#define SELECT2(t1, t2)t2
#define SELECT(n, a)PLACE(CONCAT(SELECT, n)a)


#define MATH0 (4, 1)
#define MATH1 (0, 2)
#define MATH2 (1, 3)
#define MATH3 (2, 4)
#define MATH4 (3, 0)
#define MATH(n, a)SELECT(a, CONCAT(MATH, n))


#define INC(n) MATH(n, 2)
#define DEC(n) MATH(n, 1)


int
main(void)
{
#define N 2

#define FOO1 DEC(N)

puts("FOO1 == " QUOTE(FOO1));

puts("4 - 1 == " QUOTE(DEC(4)));
puts("3 - 1 == " QUOTE(DEC(3)));
puts("2 - 1 == " QUOTE(DEC(2)));
puts("1 - 1 == " QUOTE(DEC(1)));
puts("0 - 1 == " QUOTE(DEC(0)) " - wrapped!");

puts("4 + 1 == " QUOTE(INC(4)) " - wrapped!");
puts("3 + 1 == " QUOTE(INC(3)));
puts("2 + 1 == " QUOTE(INC(2)));
puts("1 + 1 == " QUOTE(INC(1)));
puts("0 + 1 == " QUOTE(INC(0)));

return 0;
}

__________________________________________________ ________




Yes, you can do arithmetic in the preprocessor. You can even do division and
multiplication by extending the MATH macro table. One caveat, this cannot
handle negative numbers. If you try to decrement zero it will wrap to 4. If
you try to increment 4 it will wrap to zero. So, you can only work with
unsigned values.


Would this work for you?



Chris M. Thomasson
  Reply With Quote
Old 10-28-2009, 11:50 PM   #5
Chris M. Thomasson
 
Posts: n/a
Default Re: preprocessor arithmetic
"Andrey Vul" <> wrote in message
news:b58d10a4-36d7-4dc8-9104-...
> 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


You can abuse GCC. Check this out... Okay, here is the original source code:

test.c
__________________________________________________ _____________
#include <stdio.h>

#define MACRO_DEFINE #define
#define MACRO_STUB_1 QUOTEX(t)#t
#define MACRO_STUB_2 QUOTE(t)QUOTEX(t)
#define MACRO_STUB_3 FOO ## 1


MACRO_DEFINE FOO_VALUE 1
MACRO_DEFINE MACRO_STUB_1
MACRO_DEFINE MACRO_STUB_2
MACRO_DEFINE MACRO_STUB_3 FOO_VALUE


int
main(void)
{
puts("FOO1 == " QUOTE(FOO1));
return 0;
}

__________________________________________________ _____________



Now, you pre-process the above using the following command:

gcc -E -o test-pp.c test.c



Then you compile the program:

gcc test-pp.c


Finally, you run the program

../a.out


I get the following output:

FOO1 == 1





Any thoughts?

;^)



Chris M. Thomasson
  Reply With Quote
Old 10-28-2009, 11:51 PM   #6
Seebs
 
Posts: n/a
Default Re: preprocessor arithmetic
On 2009-10-28, Andrey Vul <> wrote:
> Is this because cpp only does arithmetic comparison/expansion inside
> #if ( ... ) ?


It's because the results of preprocessor expansion can never be directives.

>> But you could easily do this with pure shell, or m4, or even a C program
>> which prints C code as its output.

> Like this:
> $(CC) -E foo.c -Dn=x -Dn_=$((x-1))
> ?


No.

I'd probably do it in shell, but that question would instantly become a
shell or unix question.

-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 10-28-2009, 11:52 PM   #7
Andrey Vul
 
Posts: n/a
Default Re: preprocessor arithmetic
On Oct 28, 6:39*pm, Eric Sosman <Eric.Sos...@sun.com> wrote:
> * * *Andrey, from this and other recent threads I gather that you
> are trying to use (or abuse) the preprocessor in some very tricky
> ways. *I offer two pieces of advice: (1) don't do it, and (2) if
> you simply cannot resist doing it, wait until you are *already*
> an expert in the use of the preprocessor.
>

I'm spoiled by template metaprogramming with its sequence point
parameters and want to go back to C macros.
Any help with regards to the details of CPP (without getting into
platform-specifics)? I.e. how to structure defines so that #define a b
#define b c doesn't turn to #define a c , etc. ?


Andrey Vul
  Reply With Quote
Old 10-28-2009, 11:54 PM   #8
Andrey Vul
 
Posts: n/a
Default Re: preprocessor arithmetic
On Oct 28, 7:52*pm, Andrey Vul <andrey....@gmail.com> wrote:
> On Oct 28, 6:39*pm, Eric Sosman <Eric.Sos...@sun.com> wrote:> * * *Andrey, from this and other recent threads I gather that you
> > are trying to use (or abuse) the preprocessor in some very tricky
> > ways. *I offer two pieces of advice: (1) don't do it, and (2) if
> > you simply cannot resist doing it, wait until you are *already*
> > an expert in the use of the preprocessor.

>
> I'm spoiled by template metaprogramming with its sequence point
> parameters and want to go back to C macros.
> Any help with regards to the details of CPP (without getting into
> platform-specifics)? I.e. how to structure defines so that #define a b
> #define b c doesn't turn to #define a c , etc. ?


Apart from boost/preprocessor, that is.


Andrey Vul
  Reply With Quote
Old 10-29-2009, 12:03 AM   #9
Andrey Vul
 
Posts: n/a
Default Re: preprocessor arithmetic
On Oct 28, 7:54*pm, Andrey Vul <andrey....@gmail.com> wrote:
> Apart from boost/preprocessor, that is.


Which uses preprocessor lookup tables for pp arithmetic.


Andrey Vul
  Reply With Quote
Old 10-29-2009, 01:07 AM   #10
Andrey Vul
 
Posts: n/a
Default Re: preprocessor arithmetic
On Oct 28, 7:50*pm, "Chris M. Thomasson" <n...@spam.invalid> wrote:
> "Andrey Vul" <andrey....@gmail.com> wrote in message
>
> news:b58d10a4-36d7-4dc8-9104-...
>
> > 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

>
> You can abuse GCC. Check this out... Okay, here is the original source code:
>
> test.c
> __________________________________________________ _____________
> #include <stdio.h>
>
> #define MACRO_DEFINE #define
> #define MACRO_STUB_1 QUOTEX(t)#t
> #define MACRO_STUB_2 QUOTE(t)QUOTEX(t)
> #define MACRO_STUB_3 FOO ## 1
>
> MACRO_DEFINE FOO_VALUE 1
> MACRO_DEFINE MACRO_STUB_1
> MACRO_DEFINE MACRO_STUB_2
> MACRO_DEFINE MACRO_STUB_3 FOO_VALUE
>
> int
> main(void)
> {
> * * puts("FOO1 == " QUOTE(FOO1));
> * * return 0;
>
> }
>
> __________________________________________________ _____________
>
> Now, you pre-process the above using the following command:
>
> gcc -E -o test-pp.c test.c
>
> Then you compile the program:
>
> gcc test-pp.c
>
> Finally, you run the program
>
> ./a.out
>
> I get the following output:
>
> FOO1 == 1
>
> Any thoughts?


I got that far on my own, the only challenge left is to implement
TOKEN-- equivalent without using lookup macros.
Yet tail recursion is becoming a problem.

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?
I use #ifndef RECURSION ... #endif to shield the non-recursive part
and #if (TOKEN > 1) TOKEN * (DEC(TOKEN)) #endif
but DEC has no
DEC1 0
DEC2 1
....
lookup.


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