一个全局变量的编译错误引出的思考

因为对单元测试工具比较熟悉,今天一个同事请我帮忙解决一个UT代码编译错误的问题。字面上错误大体是说有4个变量无法找到定义。
这里先说明,我们的产品代码使用C语言编写的,UT采用cpputest,UT采用C++风格编写。

首先,我让她简单介绍产品代码和UT代码。我发现这四个变量都是全局变量,在Data.h中使用extern声明,同时在A.c中定义。然而出问题的被测代码是B.c所对应的UT,B.c引用了Data.h头文件。直观来看貌似没有问题。

我试探性的让先她在UT代码开头直接引用A.c,很快 发现A.c并没有引用Data.h。之前听该同事介绍代码时没有发现问题,因为使用的是SourceInsight编辑和走查代码,该工具并没有严格按照语法规则决定声明和定义的关系来跳转。此外,不知道什么原因产品代码make的时候也没有报错。

修改之后重新编译,又解决了几个其他的编译问题之后,这4个变量顺利找到定义并运行通过。

我们的产品代码中关于全局变量误用引入的问题我还遇到过很多奇葩事:
  1. A.h中声明并且定义全局变量。在B.c和C.c中都引用A.h,试图使用这个全局变量。
  2. A.h中声明全局变量,在B.c中再次extern声明和定义这个变量。
现在,在很多公司,遇到一个追求完美编码的同行非常少了,很多都是能运行就行,或者只管自己使用方便就行。

其实,我非常不喜欢使用全局变量,好的代码应该严格遵守开放封闭原则,而全局变量的定义显然破坏了这一原则。写C语言代码的时候,我采用的方法一般是在定义静态变量,并且针对这个静态变量提供对外的操作接口,这样外部函数如果需要使用这个变量,完全可以通过统一的接口来调用。

但是,遗憾的是,我们代码中这样的全局变量非常普遍,而且要命的是,这种变量作为数据库存储大量的数据,很多不同的模块代码可以对其进行访问操作,风险很大。

此外,如同对全局变量的态度一样,你很容易发现C程序员对C++的态度明显的分为两类:
一类以Linux的鼻祖Linus Torvalds为代表:鄙视C++语言与C++程序员,认为C++的所有新特性都是垃圾,一无是处。为此,
Torvalds多次公开的和Google以及微软的C++程序员争吵甚至直接爆粗口。
另一类C程序员则客观的承认C++语言的优点,并且利用这些长处改善C语言程序编写规范。

我对《代码大全》还是比较推崇的,你会发现第二版采用面向对象的视角重新对第一版的很多内容进行了改写。任何一门语言都如同我们人一样,必然经过生老病死的各个阶段,如果它自身有纠错的改进能力,那么它的寿命将随着它的优秀代码继续存在下去,不信你可以看看lisp语言开发的优秀系统G2。

归根结底,我想说如果你是一个从来没有使用过其他语言的C程序员,你应该至少学习了解一下C++、JAVA、Object-C这样的主流面向对象语言,再学习一下Python、Ruby等新一代的语言。他们都是工具,我们使用工具解决具体的问题,至于使用什么工具,完全取决于这些工具的特性是否更适合以及后续的 持续 可维护性以及健壮性。

你可能感兴趣的:(C++,C)