将循环放在C宏中

时间:2013-07-25 19:04:59

标签: c syntax do-while c-preprocessor

我正在寻找一种将以下函数结构转换为宏的方法。我知道,这是一个愚蠢而毫无意义的例子,但它说明了这一点,因为我无法透露我的实际源代码。

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);

3 个答案:

答案 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; })

以上结果将是最后一个表达。


在评论中,您表达:

  

我需要保存xy的新值,以便后续调用此函数foo。显而易见的方法是将指针传递给{{1 }和x然后只是制作一个常规的内联函数。但是我不想这样做,因为我正在制作一个时间关键的应用程序,我需要yx保留在寄存器中。

您假设yx不会留在寄存器中,这是不好的假设。这取决于编译器优化代码的能力。请考虑以下事项:

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)

这里的一个问题是多行宏在每一行的末尾需要\