Velocity Reviews > Macro function syntax

Macro function syntax

Ann O'Nymous
Guest
Posts: n/a

 07-28-2010
I have a macro function that's like the following:

int function2(int*,int,int,int);

#define xyz(a,b,c) {\
int x[100],i; \
for(i=0;i<c;i++) x[i] = something(a,b,c); \
function2(x,a,b,c); \
}

where "something" is a mathematical expression of a,b and c, and
"function2" is a function returning int.

Calls like:

xyz(1,2,3);

work fine, other than the return value of "function2" gets thrown away.

Now, if I want to do this:

int jkl;
....
jkl = xyz(1,2,3);
....

where "jkl" is to get that value returned by "function2", how do I do
it? I'm having trouble with the syntax.

I want things to expand where:

jkl = xyz(p,q,r);

expands equivalently to:
{
int x[100],i;
for(i=0;i<r;i++) x[i] = something(p,q,r);
jkl = function2(x,p,q,r);
}

Ann O'Nymous
Guest
Posts: n/a

 07-29-2010
On 7/28/2010 7:00 PM, pete wrote:
>
> #define xyz(a,b,c,jkl) {\
>

Thanks, but I can't actually do this. I simplified my problem, and am
actually using a variadic argument list.

Ben Bacarisse
Guest
Posts: n/a

 07-29-2010
Ann O'Nymous <(E-Mail Removed)> writes:

> On 7/28/2010 7:00 PM, pete wrote:
>>
>> #define xyz(a,b,c,jkl) {\

>
> Thanks, but I can't actually do this. I simplified my problem, and am
> actually using a variadic argument list.

Without the actual code (including the full range of calls that might

There is a big picture question that might help to have answered. Why
not use a function? The answer may be that you can't re-write the two
called functions to take a va_list, but that as least rules out the
obvious solution.

--
Ben.

Ann O'Nymous
Guest
Posts: n/a

 07-29-2010
On 7/29/2010 9:50 AM, Ben Bacarisse wrote:
> Ann O'Nymous<(E-Mail Removed)> writes:
>
>> On 7/28/2010 7:00 PM, pete wrote:
>>>
>>> #define xyz(a,b,c,jkl) {\

>>
>> Thanks, but I can't actually do this. I simplified my problem, and am
>> actually using a variadic argument list.

>
> Without the actual code (including the full range of calls that might
>
> There is a big picture question that might help to have answered. Why
> not use a function? The answer may be that you can't re-write the two
> called functions to take a va_list, but that as least rules out the
> obvious solution.

OK. I simplified things so I'd get a generic answer so I'd know what to
do next time. This is what I have at the moment:

void buildlist(unsigned int *,...);

{unsigned int list[MAXARGS];\
buildlist(list,__VA_ARGS__);\
}

"routine" is a function (one of many) called by zlink with a specialized
parameter list in array list, and the functions cannot be changed. It
returns int.

The "j=zlink()" is a hack to get the return value out.

Calls are like this:

int returnvalue1,returnvalue2;
int j;
int module1(int,...),module2(int,...);
....
returnvalue1=j;
....
returnvalue2=j;
....
I'd like to eliminate the "j=zlink() hack and change things so calls are
like this:

David Resnick
Guest
Posts: n/a

 07-29-2010
On Jul 29, 1:06*pm, Ann O'Nymous <(E-Mail Removed)> wrote:
> void buildlist(unsigned int *,...);
>
> * *{unsigned int list[MAXARGS];\
> * *buildlist(list,__VA_ARGS__);\
> * *}
>
> "routine" is a function (one of many) called by zlink with a specialized
> parameter list in array list, and the functions cannot be changed. *It
> returns int.
>
>

> The "j=zlink()" is a hack to get the return value out.
>
> Calls are like this:
>
> int returnvalue1,returnvalue2;
> int j;
> int module1(int,...),module2(int,...);
> ...
> returnvalue1=j;
> ...
> returnvalue2=j;
> ...
> I'd like to eliminate the "j=zlink() hack and change things so calls are
> like this:
>

Why not put the return value as a LINKX argument before the valist?
as in
....

Usage:

This is what pete was suggesting I'd guess, why did you think it a bad
idea?

-David

Ben Bacarisse
Guest
Posts: n/a

 07-29-2010
Ann O'Nymous <(E-Mail Removed)> writes:
<snip>
> OK. I simplified things so I'd get a generic answer so I'd know what
> to do next time. This is what I have at the moment:
>
> void buildlist(unsigned int *,...);
>
> {unsigned int list[MAXARGS];\
> buildlist(list,__VA_ARGS__);\
> }
>
> "routine" is a function (one of many) called by zlink with a
> specialized parameter list in array list, and the functions cannot be
> changed. It returns int.
>
>
> The "j=zlink()" is a hack to get the return value out.
>
> Calls are like this:
>
> int returnvalue1,returnvalue2;
> int j;
> int module1(int,...),module2(int,...);
> ...
> returnvalue1=j;
> ...
> returnvalue2=j;
> ...
> I'd like to eliminate the "j=zlink() hack and change things so calls
> are like this:
>

What other bits of C99 can you use? If you can use compound literals
you can turn the macro into a expression provided that you can change
buildlist to return a pointer to its list:

buildlist((unsigned int[MAXARGS]){0}, __VA_ARGS__));

Alternatively, you might be able to share the temporary array:

(buildlist(shared_list, __VA_ARGS__),\

You then need to define shared_array in the containing block. If
buildlist can use a static array and return that you could write:

There is also a gcc-specific solution using ({}).

--
Ben.

Ann O'Nymous
Guest
Posts: n/a

 07-29-2010
On 7/29/2010 1:40 PM, David Resnick wrote:
> Why not put the return value as a LINKX argument before the valist?

....
> This is what pete was suggesting I'd guess, why did you think it a bad
> idea?

It's not a bad idea, and it's probably what I'll be doing. It just
seems that there has to be a better way, a C function macro should be
able to act like a function. I just want the code to look like a
function call, since the called routines are often functions.

However, some of the time, they are not functions, or the function
return value is ignored, meaning the extra parameter is not really
used.

So, is there a way to rewrite LINKX to be able to use the syntax
If not, I'll add the extra parameter.

Also to Kenneth B, I am aware of the "do {...} while (0)" issue and may
do that if I have calls like you mention. In fact, I'm sure I will have
to do that.
Also is "x = do {...} while (0);" valid C syntax? (if so, what does x
get set to?)

Keith Thompson
Guest
Posts: n/a

 07-29-2010
Ann O'Nymous <(E-Mail Removed)> writes:
> On 7/29/2010 1:40 PM, David Resnick wrote:
>> Why not put the return value as a LINKX argument before the valist?

> ...
>> This is what pete was suggesting I'd guess, why did you think it a bad
>> idea?

>
> It's not a bad idea, and it's probably what I'll be doing. It just
> seems that there has to be a better way, a C function macro should be
> able to act like a function. I just want the code to look like a
> function call, since the called routines are often functions.

[...]

There is no such thing as a "function macro" or a "macro function" in C.
There are "function-like macros", but those are merely macros with
parameters.

Keep in mind that macro expansion is almost purely textual, and applies
only to the macro invocation itself. For example, given:

x = MY_MACRO(y, z);

the expansion of MY_MACRO can't do anything with x.

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(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"

Shao Miller
Guest
Posts: n/a

 07-30-2010
#define MAXARGS 10

int zlink(int(int, ...), int, unsigned int *);
int zlink(int bar(int, ...), int flags, unsigned int *list) {
return 12;
}

unsigned int *buildlist(zlink_args list, ...) {
/* ... */
return list;
}

int foo(int bar, ...) {
return 5;
}

int main(void) {
int w, x, y, z;

w = x = y = z = 10;
return LINKX(foo, (1 << 3) & (1 << 4), mylist, w, x, y, z);
}

Shao Miller
Guest
Posts: n/a

 07-30-2010
On Jul 29, 8:34*pm, Shao Miller <(E-Mail Removed)> wrote:
> * return LINKX(foo, (1 << 3) & (1 << 4), mylist, w, x, y, z);

'|', not '&'.