标签 Compiler 下的文章

追求'lint-clean'

到底需不需要编译器之外的独立的静态代码检查工具呢?这个问题’仁者见仁,智者见智’。但是有一个结论我想大家都会认可,那就是越是在开发周期早期发现的Bug,修复它所付出的代价就越小。而像lint这样的静态代码检查程序恰恰是让Bug在早期阶段’显露原型’的绝佳工具,而追求’lint-clean’[注1]境界的代码也向来是专家级程序员的嗜好。别忘了在’C专家编程’一书中曾经提到Sun OS的内核一直是保持’lint-clean’状态的,这就是榜样!还等什么?赶快学呀!^_^

有人抱怨’不敢用lint工具, 太多的Warnings把快屏幕都淹没了!’,不过高手一般不这么想,他会细心琢磨这些Warnings背后的’暗示’,并和lint工具沟通,利用lint工具提供的交互方法屏蔽掉一些经过分析认为不能成为错误的Warnings。久而久之,高手本身就成了一个lint程序,就能够很快的用肉眼发现代码中的问题,并指出问题所在,如何解决!他还能告知如何嵌入一些Annotations从而避免让lint程序产生不必要的Warnings,这时这位高手对语言和程序的理解就又提高了一个档次了。其实使用ling工具不仅仅是为了提早发现程序中的Bug,其使用过程有助于你加深对程序的认识和理解。的确事实就是这样。

Splint就是一款强大而且应用广泛的开源lint工具。它的强大的代码检查能力固然让人称道,但是让我更欣赏的却是它提供的’Annotations’机制。Splint可以让程序员在自己的代码中嵌入相应的Anotations,这些Anotations作为Splint分析代码时的输入以帮助Splint产生对程序员更有用的信息。下面是一些Splint的使用入门,更多详细信息请查看’Splint manual‘。

1、最简单的Splint使用方法
>> splint *.c

2、Splint输出Warnings的基本格式
<file>:<line>[,<column>]: message
     [hint]
      <file>:<line>,<column>: extra location information, if appropriate
我们可以使用’+/-<flags>’来自定义其输出格式,如’splint -showcol *c’,则Splint不会在输出信息中显示’列’信息。

3、使用flags控制splint的检查范围和输出格式
‘+<flag>’ — 表明某个flag处于打开状态,如’+unixlib’;
‘-<flag>’ — 表明某个flag处于关闭状态,如’-weak’;

4、使用.splintrc环境文件
如果不想每次使用splint的时候都手工输入一堆’+/-<flags>’,那么你可以把这些’+/-<flags>’预先写到.splintrc文件中,当splint执行的时候它会自动加上这些flags的。默认的flags设置在’~/splintrc’文件中,但是如果一旦splint的当前工作路径下也有.splintrc文件,那么这个.splintrc文件中的flag设置会覆盖’~/splintrc’中的flags设置,但是命令行中的flags设置是具备最高优先级的,它会覆盖前面提到的任何一个文件中的flags设置。

5、使用Annotations
对于’Annotations’的作用,Java程序员并不陌生,但是C程序员则对这个不是那么了解。C代码中的Annotations用来指导Splint生成恰当的代码检查报告。下面这个例子对比使用和不使用Annotations,Splint的输出的差别:
/* testlint.c */
void foo1() {
        /*@unused@*/int *p = NULL;
}

void foo2() {
        int *p = NULL;
}

splint testlint.c
Splint 3.1.1 — 28 Apr 2003

testlint.c: (in function foo2)
testlint.c:6:7: Variable p declared but not used
  A variable is declared but never used. Use /*@unused@*/ in front of
  declaration to suppress message. (Use -varuse to inhibit warning)

Finished checking — 1 code warning

可以看出没使用Annotation的函数foo2被给出Warning了。Splint的Annotations繁多,我们在平时做lint时可以多多接触。

‘早用lint,勤用lint’,这是C专家给我们的建议。’lint-clean’也许离你并不遥远。

[注1]
‘lint-clean’ — 程序能够顺利通过lint程序的检查。

差异学习

看了dreamhead的那篇“差异程序员”,又恰逢在今天dreamhead在一封邮件中谈到其继续深入“向下学习”的想法,心里突然有了本篇题目这样的一个话题。

“差异程序员”(http://dreamhead.blogbus.com/logs/2005/12/1676755.html)

最近自己也在“向下走”,这和dreamhead的想法和做法不谋而合。dreamhead在其blog和邮件中都谈了其在“向下走”过程中的体会,“差异程序员”一篇dreamhead也是在告诉大家其不满足于只做应用一层的程序员,这也同样是我的一些想法。

想法有了,那我们是如何做的呢?mail中dreamhead谈到了他下一步的学习目标和计划,在我的回复mail中我也谈了我将在linux内核方面和编译技术方面作些努力的初步想法。dreamhead也马上谈了他关于这两方面的看法,这里引用少许,目的在对比:
“编译器的前端相对来说都是简单的,技术基本都是现成的,而且有现成的工具供人使用,当然,为了学习,还是自己尝试写一遍比较好。后端的东西才是真正复杂的,不同的平台不同的OS都会有不同的要求,之后,还有优化的技术,复杂度直线上升。… … 如果想了解OS运作,Linux内核显然过于庞大了,那本《自己动手写操作系统》则更为简单。一些基础的东西是类似的,只要理解了那个小内核,理解Linux只是更好的去体会更好的设计而已,因为所有的知识已经都各就其位了,一旦架构形成,剩下的只是不断完善了。”

看到这样的回复,我马上意识到:虽然都是向下走,但是我和dreamhead的目的不同,形成的想法就有了些差异。

我之所以想啃下编译,原因起初有二:一是在前不久的工作中想采用编译中的技术来完成项目中一个模块的功能;二是填补大学时没有学懂编译的遗憾,就是想弄懂那些三元式、四元式,让自己更专业一些。上星期看了“dragon book[注1]”作者的一席话又为我学习编译增加了一枚筹码,其大致意思就是:大多数学习编译的人一生都可能没有机会去创造一门语言,那么我们为什么还学习编译呢?其中一个原因就是编译技术中某些原理可以适用于一般应用软件的设计。比如词法分析器中的字符串匹配技术可用于文本编辑器、信息获取系统或者模式识别程序中。

对于学习linux内核我有以下几点考虑:首先一直在用户层使用内核提供的系统调用,比如fork,在很多Unix编程书中会讲到调用fork后子进程与父进程的异同,这些几乎就是应用程序员必须牢记的东西,一直很讨厌强记,遂想刨根问底的去看看fork的一些实现,这样弄清了其来龙去脉就再无须强记了,而弄清了这些后反过来又会让你更好的使用这些系统调用;其次,想在用户层程序中借鉴内核的优秀设计思想,比如缓冲技术,在内核中有在应用层也有,应用层完全可以参考内核中的某些优秀设计来实现;最后,了解操作系统内核会让你对计算机的体系的理解有一个质的飞跃。即使是计算机本科毕业的人又有多少敢说自己完全理解了计算机呢。

dreamhead以了解OS运作为目的向我们推荐《自己动手写操作系统》一书自然没错,带着这样的目的来学习这本书效果肯定也不错;但是对于我上面所说的那些目的,这本书也仅能满足一小部分,该书可以作为整个学习过程中的一个参考资料。这就是由于学习目的不同带来的一些差异性的东西。

差异学习没有对错之分,也没有好坏之分,只是因目的不同而已罢了。目的不同,学习的关注点和着重点就会不同,这样即使学习同一样的技术效果也不同。另外学习不是孤立的,沿着学习的主线方向会有很多旁支,如学习linux内核,你将会了解到CPU体系结构、存储器管理和算法理论等多方面的知识。

最近看到某一电视台播放的央视版“笑傲江湖”,情节中提到华山剑宗与气宗之争,当时自己就考虑“为何两派不二者兼修以达到前所未有之境界呢”,在后来的令狐冲无心插柳却达到了这一境界,想必那些在两宗相争中冤死的华山前辈们看到这一结局都后悔之极了吧。(开个玩笑,其实从古自今大凡争斗之事多源自“权势之争”)。令狐冲成为了绝顶高手又让我想到了“差异程序员”,要想成为“程序界”的令狐冲又何尝不需要“上下”兼修呢?起码dreamhead已经为我们作出了表率。

[注1]
“dragon book” — 《Compilers: Principles, Techniques and Tools》by Aho, Sethi and Ullman

如发现本站页面被黑,比如:挂载广告、挖矿等恶意代码,请朋友们及时联系我。十分感谢! Go语言第一课 Go语言精进之路1 Go语言精进之路2 商务合作请联系bigwhite.cn AT aliyun.com

欢迎使用邮件订阅我的博客

输入邮箱订阅本站,只要有新文章发布,就会第一时间发送邮件通知你哦!

这里是 Tony Bai的个人Blog,欢迎访问、订阅和留言! 订阅Feed请点击上面图片

如果您觉得这里的文章对您有帮助,请扫描上方二维码进行捐赠 ,加油后的Tony Bai将会为您呈现更多精彩的文章,谢谢!

如果您希望通过微信捐赠,请用微信客户端扫描下方赞赏码:

如果您希望通过比特币或以太币捐赠,可以扫描下方二维码:

比特币:

以太币:

如果您喜欢通过微信浏览本站内容,可以扫描下方二维码,订阅本站官方微信订阅号“iamtonybai”;点击二维码,可直达本人官方微博主页^_^:
本站Powered by Digital Ocean VPS。
选择Digital Ocean VPS主机,即可获得10美元现金充值,可 免费使用两个月哟! 著名主机提供商Linode 10$优惠码:linode10,在 这里注册即可免费获 得。阿里云推荐码: 1WFZ0V立享9折!


View Tony Bai's profile on LinkedIn
DigitalOcean Referral Badge

文章

评论

  • 正在加载...

分类

标签

归档



View My Stats