将循环放在C宏内 [英] Putting loop inside C macro
问题描述
我正在寻找一种将以下函数结构转换为宏的方法。我知道,这是一个愚蠢且毫无意义的示例,但它说明了这一点,因为我无法给出实际的源代码。
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.
}
这样我就可以在main或其他一些类似的函数中调用该函数:
So that I can call the function in main or some other function like so:
int next_x = foo(x,y);
我似乎无法在此处使语法100%正确。这是我的错误尝试:
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 \
)
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.
============================= =================
===============================================
我还应该注意,我还有其他一些相应构造的宏:
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);
推荐答案
C语法仅允许用逗号运算符(,
)。 do ... while()
不是表达式,而是语句,因此将其用作逗号运算符的值是错误的。
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.
#define FOO(x, y, result) \
do { \
do { \
--x; \
++y; \
} while(x > y); \
result = x * y; \
} while(0)
如果您使用的是GCC,则可以使用语句表达语法,它是C语言的扩展,而不是标准的C功能。语法如下:
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:
({ statement; statement; expression; })
上面的结果将是最后一个表达式。
And the result of the above would be the last expression.
在评论中,您表示:
我需要保存
x的新值
和y
,用于对该函数的后续调用foo
。将传递指向x
和y
的指针,然后仅创建常规的内联函数。但是我不想这样做,因为我正在制作时间紧迫的应用程序,因此需要x
和y
I need to save the new values of
x
andy
for subsequent calls to this functionfoo
.. The obvious way to do this would be to pass pointers tox
andy
and then just make a regular, inlined function. However I do not want to do that because I'm making a time critical application and I needx
andy
to remain in registers.
您假设 x
和 y
不会留在寄存器中,这是一个错误的假设。这取决于编译器优化代码的能力。请考虑以下内容:
You are assuming that x
and y
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:
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 $ c编译时$ c>,结果是:
main:
.LFB14:
movl %edi, %edx
.L2:
movl %edi, %eax
addl $1, %edx
subl $1, %edi
cmpl %edx, %eax
jg .L2
movl $0, %eax
ret
.LFE14:
您将发现没有指针值取消引用,这正是您想要发生的事情。
You will observe there is no pointer value dereference, which is exactly what you wanted to have happen.
这篇关于将循环放在C宏内的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!