variadic arithmetic, boolean operators

T

Trent Buck

(Note: C99 supports variadic macros, but C89 does not.)

I'm pretty sure what I'm trying to do is impossible, but I'll ask here
in case I'm missing something.

I'm trying to define generic, variadic arithmetic and boolean operators.
For example,

product (2, sum (3, 4), 5);

should expand to

(2) * ((3) + (4)) * (5);

Here is my pseudocode:

#define sum(x,y) \
(x) + (y)

#define sum(x, y, ...) \
(x) + sum (y, __VA_ARGS__)

int main (void)
{
sum (1, 2, 3, 4);
return 0;
}

Unfortunately, this has two problems:

- Macros cannot be overriden, hence the base case cannot be caught
generically. (You can define the base case as a function if the
definition (and declaration) precede the macro definition.)

- Macros expansion is not recursive (apparently).

For example, GCC's preprocessor outputs the following:

tmp.c:4:1: warning: "sum" redefined
tmp.c:1:1: warning: this is the location of the previous definition
# 1 "tmp.c"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "tmp.c"






int main (void)
{
(1) + sum (2, 3, 4);
return 0;
}

Can someone please either confirm that this is impossible in C, or
suggest how to go about it?
 
T

Thomas Matthews

Trent said:
(Note: C99 supports variadic macros, but C89 does not.)

I'm pretty sure what I'm trying to do is impossible, but I'll ask here
in case I'm missing something.

I'm trying to define generic, variadic arithmetic and boolean operators.
For example,

product (2, sum (3, 4), 5);

should expand to

(2) * ((3) + (4)) * (5);

Here is my pseudocode:

#define sum(x,y) \
(x) + (y)

#define sum(x, y, ...) \
(x) + sum (y, __VA_ARGS__)

int main (void)
{
sum (1, 2, 3, 4);
return 0;
}

Unfortunately, this has two problems:

- Macros cannot be overriden, hence the base case cannot be caught
generically. (You can define the base case as a function if the
definition (and declaration) precede the macro definition.)

- Macros expansion is not recursive (apparently).

My suggestion is to change your design so that you are passing
containers (lists, vectors, arrays, etc.) to each function. Each
function would return the result. This design would eliminate
the need for variable argument lists.

int sum(int * array_of_integers,
unsigned int num_integers)
{
int result;
unsigned int index;
for (index = 0, result = 0;
index < num_integers;
++index)
{
result += *array_of_integers++;
}
return result;
}


--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.comeaucomputing.com/learn/faq/
Other sites:
http://www.josuttis.com -- C++ STL Library book
http://www.sgi.com/tech/stl -- Standard Template Library
 
T

Trent Buck

Up spake Thomas Matthews:
My suggestion is to change your design so that you are passing
containers (lists, vectors, arrays, etc.) to each function. Each
function would return the result. This design would eliminate
the need for variable argument lists.

Not a solution I'm particularly taken with, but better than anything I
had come up with. Thank you.
 
M

Mysidia

If using gcc, I might say use the ({}) extension:

#define sum(s...) \
({ int args[] = { s }; \
mysum(args, sizeof(args)/sizeof(*args)); \
})

int mysum(int args[], int n)
{
int i,w=0;

for(i=0;i<n;i++) w+= args;
return w;
};


For C99, perhaps a make_list macro could be a useful
approach... so you would have

make_list(list, 3,4,5,6)
sum(list);

struct List {
int *arr;
int len;
};

#define make_list(L,...) \
do {
int args[] = { __VA_ARGS__ };
int len = sizeof(args) / sizeof(*args);
L.args = args;
L.len = len;
} while(0)


-Jmh
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top