|为什么我不建议使用宏来控制代码流?

|为什么我不建议使用宏来控制代码流?

文章图片

|为什么我不建议使用宏来控制代码流?

平常的我基本不怎么生气 , 但有时候还是会忍不住 。 今天 , 我要特意指出一个让我感到不悦的地方:使用宏来对代码流进行控制 。
对于宏来说 , 没有两个开发者会使用相同的宏 , 当你看到一些不太常见的宏调用时 , 如果你想弄明白代码的流程 , 你将不得不到头文件中仔细研究宏的定义 。
特别是当你调试其他人编写的代码的时候 。 举个例子 , 如果在一段代码中 , 你看到一个进入临界区的代码 , 如果函数里面的代码只有return或者goto之类代码流控制语句 , 则很容易看出临界区是否能正常的释放 , 但是 , 如果开发者将这些控制语句隐藏在一个又一个的宏里面 , 则就不那么容易看出来了 。
下面是一个例子
在上面的代码中 , 你可能会有很多疑问 。
> 临界区是否存在泄漏的可能?
> 如果BLOCK校验失败 , 会发生什么?
> 如果DoSomethingElse失败了 , DoSomethingAgain会得到调用吗?
> “Cleanup”这个标签并没有使用到 , 为什么?
> 有没有一种执行流程会导致”hr”变量未初始化?
以上这些问题 , 你必须去到宏定义的头文件里 , 仔细研究VALIDATE_BLOCK , TRAP_FAILURE和MUST_SUCCEED这些宏到底在干嘛 。
(的确 , 我们可以通过使用带有析构函数的锁定对象来避免临界区问题 , 但这不是我想表达的重点 。 另外还需要注意 , 这个函数会在程序执行途中退出临界区 。 大多数锁定对象不支持这种功能 , 如果需要添加这个功能 , 则需要添加额外的成员变量才行)
当你编写流程控制宏时 , 实际上 , 你正在修改语言本身 。 当在代码编辑器中打开一个CPP文件时 , 我希望我看到的将是C++代码 , 而不是一些与C++非常相似的奇怪方言 。(出于这个原因 , 我很庆幸C#不支持宏 。 )
如果说了这么多 , 还是有人喜欢流控制宏的人 , 那么请看看原始版本的Bourne shell的代码 , 如下图是它的一个代码片段 , 大家感受一下:

在那个时代 , 这段代码就被当作”死于宏”的一个范例 , 因为它的代码严重依赖于宏 , 以至于没有人能理解它 。可怕的是 , 按照今天的标准 , 它还是相当”温顺”的 , 如果你看看现在的代码的话 。
总结总而言之 , 言而总之:请尽量不使用”体现你高超的代码技艺”的宏 。
总会有人需要阅读你的代码 , 甚至需要做一些维护 。
代码人何苦为难代码人 。
最后Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一 , 里面有很多关于Windows的小知识 , 对于广大Windows平台开发者来说 , 确实十分有帮助 。
本文来自:《A rant against flow control macros》
【|为什么我不建议使用宏来控制代码流?】