我在 C++ 环境中工作并且:
a) 我们禁止使用异常
b) 评估大量不同类型请求的应用程序/数据服务器代码
我有一个简单的类封装了服务器操作的结果,它也在内部用于那里的许多功能。
class OpResult
{
.....
bool succeeded();
bool failed(); ....
... data error/result message ...
};
当我尝试让所有函数都变得小而简单时,出现了很多像这样的 block :
....
OpResult result = some_(mostly check)function(....);
if (result.failed())
return result;
...
问题是,让宏看起来像这样并在任何地方都使用它是一种不好的做法吗?
#define RETURN_IF_FAILED(call) \
{ \
OpResult result = call; \
if (result.failed()) \
return result; \
}
我知道有人会说它很讨厌,但是有更好的方法吗? 您还有什么其他处理结果和避免大量膨胀代码的方法?
最佳答案
这是一个权衡。您正在交易代码大小以混淆逻辑。我更愿意保留可见的逻辑。
我不喜欢这种类型的宏,因为它们会破坏 Intellisense(在 Windows 上)和程序逻辑的调试。尝试在函数中的所有 10 个 return
语句上放置一个断点 - 而不是检查,只是 return
。尝试单步执行宏中的代码。
最糟糕的是,一旦您接受了这一点,就很难反驳某些程序员喜欢将其用于常见的小任务的 30 行巨型宏,因为它们可以“澄清事情”。我已经看到代码,其中不同的异常类型由四个级联宏以这种方式处理,导致源文件中有 4 行,宏实际上扩展到超过 100 行。现在,您正在减少代码膨胀吗?不。用宏不可能轻易分辨。
另一个反对宏的一般论点,即使在这里显然不适用,是能够将它们与难以破译的结果嵌套,或者传递导致奇怪但可编译的参数的参数,例如在使用参数两次的宏中使用 ++x
。我总是知道我对代码的立场,但我不能这样说宏。
编辑:我应该补充的一个评论是,如果您确实一遍又一遍地重复此错误检查逻辑,那么代码中可能存在重构机会。如果确实适用,这不是保证,而是减少代码膨胀的更好方法。查找重复的调用序列并将公共(public)序列封装在它们自己的函数中,而不是单独解决每个调用的处理方式。
关于C++代码纯度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4172545/