如果!= 0,则C宏返回函数结果

时间:2019-11-26 10:24:03

标签: c macros c-preprocessor

我有一个C函数,该函数调用其他函数,每个函数返回int,其中0正常,如果!= 0,则返回错误代码。该函数如下:

int myfunc()
{
  int err;
  err = func1(arg1);
  if (err != 0) {
    return err;
  }
  err = func2(arg2, arg3);
  if (err != 0) {
    return err;
  }
  err = func3(arg4, arg5);
  if (err != 0) {
    return err;
  }
  err = func4();
  if (err != 0) {
    return err;
  }
  return 0;
}

如您所见,我有很多样板代码:

err = some_func();
if (err != 0) {
  return err;
}

是否可以编写一些宏来简化它?像这样:

#define TRY() ???

int myfunc()
{
  TRY(func1(arg1));
  TRY(func2(arg2, arg3));
  TRY(func3(arg4, arg5));
  TRY(func4());
}

2 个答案:

答案 0 :(得分:6)

#define TRY(expression)     \
  do {                      \
    int err = (expression); \
    if (err != 0) {         \
      return err;           \
    }                       \
  } while (0)

这使err的范围限于宏。每次在单独的花括号块中使用相同的变量名都是合法的。

您仍然需要在底部return 0

int myfunc()
{
  TRY(func1(arg1));
  TRY(func2(arg2, arg3));
  TRY(func3(arg4, arg5));
  TRY(func4());
  return 0;
}

另请参阅:

答案 1 :(得分:4)

我要说的是你已经拥有的东西很好。是的,它是重复性的,但仍易于阅读。将跳转语句(例如return)隐藏在宏后面几乎不是一个好主意。

如果您坚持要缩短它,则可以使用逻辑AND或OR运算符链接函数调用:

if((err = func1(arg1))       != 0 ||
   (err = func2(arg2, arg3)) != 0 ||
   (err = func3(arg4, arg5)) != 0 ||
   (err = func4())           != 0)
{
    return err;
}

之所以起作用,是因为逻辑运算符具有短路行为。当第一个OR条件为true时,将不评估或执行其余条件。

如果由于某种原因(例如代码准则)而无法在if语句条件中进行赋值,则可以将代码链移至其上方:

(err = func1(arg1))       != 0 ||
(err = func2(arg2, arg3)) != 0 ||
(err = func3(arg4, arg5)) != 0 ||
(err = func4())           != 0;

if(err != 0) {
    return err;
}

由于if语句必须执行的唯一操作是返回错误代码,因此可以通过删除所有if语句并在函数末尾仅包含一个return语句来进一步简化该操作。 (感谢乔纳森·莱弗)

(err = func1(arg1))       != 0 ||
(err = func2(arg2, arg3)) != 0 ||
(err = func3(arg4, arg5)) != 0 ||
(err = func4())           != 0;
return err; /* Returns error code or 0. */