让宏定义为函数返回值是不好的做法吗?
使用定义为有条件返回值的宏有一个缺点,即仅查看客户端代码可能会在宏处退出,这一点并不明显。
我正在考虑的用例是编写一个值和错误检查,如下所示:
#define WRITE_CHK(file, param)\
if (!write_that_returns_zero_on_fail(file, param)) {\
handle_error();\
return false;\
}
客户端代码:
bool myfunc()
{
...
WRITE_CHK(file, param) // function might return here
...
return true;
}
我很好奇宏(将在我的代码中的许多地方使用)的好处是否会超过上面提到的缺点。 除了简单扩展(不使用宏)之外,还有其他更好的选择吗?
Using a macro defined to conditionally return a value has a disadvantage where it is not apparent from only looking at the client code might exit at the point of the macro.
The use case I am considering is writing a value and error checking, like so:
#define WRITE_CHK(file, param)\
if (!write_that_returns_zero_on_fail(file, param)) {\
handle_error();\
return false;\
}
client code:
bool myfunc()
{
...
WRITE_CHK(file, param) // function might return here
...
return true;
}
I am curious if the benefits of the macro (which would be used in many places in my code) would outweigh the disadvantage mentioned above.
Are there preferred alternatives besides simply expanding (not using the macro)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
标准答案是“不要使用宏”;但这通常有点简单化。有时,它们可以大大减少您原本会遇到的冗长的样板代码。
那么,为什么不将事实编码到宏名称中呢?例如
WRITE_OR_RETURN_ON_FAILURE
。它可能有点冗长,但不太可能让代码的读者感到困惑。The standard answer is "don't use macros"; but that's often slightly simplistic. There are sometimes cases where they can greatly cut down on the boilerplate verbosity that you'd otherwise have.
So, why not encode the fact into the macro name? e.g.
WRITE_OR_RETURN_ON_FAILURE
. It may be slightly verbose, but it's much less likely to trip up readers of your code.在宏内隐藏控制流并不常用,因此对于必须理解或调试代码的开发人员来说,这可能会造成困惑。
我建议不要完全使用宏,但如果必须使用它们,请确保控制流部分是明确的。
另一个要问自己的问题是——为什么你要在这里使用宏?如果它是为了隐藏控制流那么这不是一个好主意。难道还有别的原因吗?
Hiding control flow inside a macro is not used very commonly, so it can be confusing to developers who will have to understand or debug your code.
I would recommend against using macros totally, but if you have to use them ensure that the control flow part is explicit.
Another question to ask yourself would be -- why do you want to use macros here anyway? If it was to hide the control flow then that's not a good idea. Is there another reason?
创建一个两步宏:
然后,如果您需要在其他地方进行类似的检查,您可以创建其他包装器(或直接使用 WRITE_CHK(file, param, return false))
Make a 2-step macro:
Then you can make other wrappers if you need a similar check elsewhere (or directly use
WRITE_CHK(file, param, return false)
)是的,这很糟糕。 Use a
goto
.Edit: if you're downvoting because you don't understand what that while loop is doing there, you should just have asked. It is a standard technique for making sure a C macro acts as a single statement in any context. If your macro expands to an if statement (like the macros in the other, upvoted answers), then you get unexpected side effects, eg:
You'd expect something_else to be executed when
!a
, but what the macro actually expands to is:And something_else is executed when
a && x
, not when!a
as the programmer intended.Yes, it's bad. Use a
goto
.Edit: if you're downvoting because you don't understand what that while loop is doing there, you should just have asked. It is a standard technique for making sure a C macro acts as a single statement in any context. If your macro expands to an if statement (like the macros in the other, upvoted answers), then you get unexpected side effects, eg:
You'd expect something_else to be executed when
!a
, but what the macro actually expands to is:And something_else is executed when
a && x
, not when!a
as the programmer intended.