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

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

作者:BlogUpdater |  时间:2022-03-12 |  浏览:1011 |  评论已关闭 条评论

平常的我基本不怎么生气,但有时候还是会忍不住。今天,我要特意指出一个让我感到不悦的地方:使用宏来对代码流进行控制。

对于宏来说,没有两个开发者会使用相同的宏,当你看到一些不太常见的宏调用时,如果你想弄明白代码的流程,你将不得不到头文件中仔细研究宏的定义。

特别是当你调试其他人编写的代码的时候。举个例子,如果在一段代码中,你看到一个进入临界区的代码,如果函数里面的代码只有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》

最近我写了个东西
正如你们所知道的,拓扑梅尔智慧办公平台(Topomel Box)是一款绿色软件,主要面向经常使用电脑的朋友。它提供了各种提升办公效率的小功能,同时操作上尽可能地简单方便。
我想:你值得拥有。

标签:

评论已关闭。