我正在寻找一种将以下函数结构转换为宏的方法。我知道,这是一个愚蠢而毫无意义的例子,但它说明了这一点,因为我无法透露我的实际源代码。
int foo(int x, int y)
{
do
{
--x;
++y;
}while(x > y);
return x * y; //note that x and y have changed values here.
}
这样我就可以在main或其他函数中调用函数,如下所示:
int next_x = foo(x,y);
我似乎无法在此处获得100%正确的语法。这是我的不良尝试:
#define FOO(x,y) \
( \
do \
{ \
--x; \
++y; \
}while(x < y), \
x \
)
最后 x 的原因是理论上可以做到这一点
int next_x = FOO(x,y);
但相反,我得到一个语法错误,我不知道为什么。任何帮助将不胜感激。
===============================================
我还应该注意到我有其他相应结构的宏:
#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 \
)
所以,我可以并且做了以下事情:
float my_flt = NEXT_FLOAT(x,y,temp);
答案 0 :(得分:3)
C语法只允许表达式由逗号运算符(,
)分隔。 do ... while()
不是表达式,而是语句,因此将它用作逗号运算符的值是错误的。
一般来说,内联函数应优先于宏来执行某些内联计算。它们更易于实现,更不容易出错,并且更易于维护。很少有情况下内联函数会在宏成功的地方失败。
实际上没有一个安全的宏来实现您的目标,但解决方法是将您想要更新的变量作为宏参数传递。
#define FOO(x, y, result) \
do { \
do { \
--x; \
++y; \
} while(x > y); \
result = x * y; \
} while(0)
如果您正在使用GCC,则可以使用他们的statement-expression syntax,它是C的扩展,而不是标准C功能。语法如下:
({ statement; statement; expression; })
以上结果将是最后一个表达。
在评论中,您表达:
我需要保存
x
和y
的新值,以便后续调用此函数foo
。显而易见的方法是将指针传递给{{1 }和x
然后只是制作一个常规的内联函数。但是我不想这样做,因为我正在制作一个时间关键的应用程序,我需要y
和x
保留在寄存器中。
您假设y
和x
不会留在寄存器中,这是不好的假设。这取决于编译器优化代码的能力。请考虑以下事项:
y
使用static inline int foo (int *x, int *y) {
do {
--*x;
++*y;
} while (*x > *y);
return *x**y;
}
int main (int argc, char *argv[]) {
int x = argc+1;
int y = argc;
foo(&x, &y);
return 0;
}
编译时,结果为:
gcc -O1
你会发现没有指针值取消引用,这正是你想要发生的事情。
答案 1 :(得分:2)
您不能将do/while
循环用作表达式,因此您需要在括号内使用块,如下所示:
编辑:这是GCC扩展,而非标准C
#define FOO(x,y) \
({ \
do \
{ \
--x; \
++y; \
}while(x > y); \
x; \
})
答案 2 :(得分:0)
这里的一个问题是多行宏在每一行的末尾需要\
。