任何人都可以帮我理解这条线的含义吗?
我知道它是一种宏结构,但是在代码中提出了什么呢?
#define ReturnErr(fCall) if (iErr = (fCall), (iErr != NO_ERRORS)) {return iErr;}
答案 0 :(得分:5)
合格的猜测是宏应该像这样使用:
err_t func (void)
{
err_t iErr;
ReturnErr(some_function());
...
return NO_ERRORS;
}
在这种情况下,宏扩展为:
err_t func (void)
{
err_t iErr;
if(iErr = some_function(), iErr != NO_ERRORS) { return iErr; }
...
return NO_ERRORS;
}
反过来又是一种不必要的混淆写作方式
err_t func (void)
{
err_t iErr;
iErr = some_function();
if(iErr != NO_ERRORS)
{
return iErr;
}
...
return NO_ERRORS;
}
换句话说,宏可能是一次又一次地重复相同的错误处理代码的尝试。
答案 1 :(得分:2)
宏是文本替换。这意味着,如果有人写,例如,
ReturnErr(x)
然后他们的代码将被处理为:
if ( iErr = (x), (iErr != NO_ERRORS) )
{
return iErr;
}
这是一种糟糕的风格,但是他们可能希望在发生故障时让函数返回并节省一些打字,而不是在需要检查错误代码的每个点复制代码。
答案 2 :(得分:2)
宏采用名为fCAll
的单个参数。宏扩展为以下代码:
if (iErr = (fCall), (iErr != NO_ERRORS)) {
return iErr;
}
我猜你对if语句中,
运算符的使用感到困惑。
在C和C ++编程语言中,逗号运算符(由...表示) token
,
)是一个二元运算符,它计算第一个操作数并丢弃 结果,然后计算第二个操作数并返回该值(和类型)。
这是wikipedia article btw。
的引用因此,当且仅当iErr != NO_ERRORS
即有错误时,才会执行正文中的陈述。
答案 3 :(得分:1)
宏想要使用值iErr
两次,一次在if
,一次在return
,但是
它只想执行fCall
一次。它使用逗号来计算其操作数,但仅与最右边的数字相等。
因此,如果我们手工扩展并进行一些重构,我们得到:
iErr = (... macro argument here ...);
if((iErr != NO_ERRORS)) {
return iErr;
}
答案 4 :(得分:0)
Lundin和其他人已经解释了宏的作者的意图。但是,它的编写方式也会产生意想不到的后果,因为它不遵循编写多语句宏的规范方法,即:将它包装在do..while(0)循环中。
为什么呢?考虑:
if( someCondition) ReturnErr(fCall); else doSomethingElse();
这在语法上失败了,因为程序员在扩展宏的大括号后面的分号是一个空语句,使 else 悬空。
程序员可以选择删除多余的分号,以便安抚编译器,编写
if( someCondition) ReturnErr(fCall) else doSomethingElse();
这可能不是他/她的意图,因为 else 部分现在以静默方式附加到宏的 if 。这非常糟糕,因为它完全不可见。
规范方式是:
#define ReturnErr(fCall) do { if (iErr = (fCall), (iErr != NO_ERRORS)) \
return iErr; \
} while(0)
这允许,甚至在结尾处需要语法上自然的分号,并且只要需要一个语句就算作单个语句。
@Jens :: - )