I'm looking for a way to convert the following function structure to a macro. I know, it's a silly and pointless example, but it illustrates the point since I cannot give out my actual source code.
int foo(int x, int y)
{
do
{
--x;
++y;
}while(x > y);
return x * y; //note that x and y have changed values here.
}
So that I can call the function in main or some other function like so:
int next_x = foo(x,y);
I cannot seem to get the syntax 100% correct here. This is my poor attempt:
#define FOO(x,y) \
( \
do \
{ \
--x; \
++y; \
}while(x < y), \
x \
)
The reasoning for the x at the end is so that I could, in theory, be able to do this
int next_x = FOO(x,y);
but instead, I get a syntax error and I'm not sure why. Any help would be appreciated.
===============================================
Additional Info
I should also note that I have other macros which are structured accordingly:
#define INIT(x,y)
(
x = //something,
y = //something
)
#define NEXT_INT(x,y) \
( \
INIT(x,y), \
get_next_num(x,y) \ //Note, this is an inline function call , not a macro.
)
#define NEXT_FLOAT(x,y,temp) \
( \
temp = NEXT_INT(x,y), \
temp ? temp * 1.23456 : FLT_MIN \
)
And so, I can and have done the following:
float my_flt = NEXT_FLOAT(x,y,temp);
The C syntax only allows expressions to be separated by the comma operator (
,
).do ... while()
is not an expression, but a statement, so it is an error to use it as a value to a comma operator.Generally speaking, an inline function should be preferred over a macro to perform some inline computation. They are easier to implement, less error prone, and easier to maintain. There are very few situations where an inline function would fail where a macro would succeed.
There really isn't a safe macro to achieve your objective, but a workaround would be to pass the variable you want updated in as a macro parameter.
If you are using GCC, you can use their statement-expression syntax, which is an extension to C, and not a standard C feature. The syntax is like:
And the result of the above would be the last expression.
In a comment, you express:
You are assuming that
x
andy
would not be left in registers, which is bad assumption to make. It depends on the quality of your compiler's ability to optimize code. Consider the following:When compiled with
gcc -O1
, the result is:You will observe there is no pointer value dereference, which is exactly what you wanted to have happen.
You cannot use
do/while
loops as an expression, so you'll need to use a block within parentheses, like this:EDIT: this is a GCC extension, not standard C
One issue here is that multiline macros require a
\
at the end of each line.