PC-Lint终于迎来了9.0版本

从2001年的8.0、8.0a一直走到2008年的8.0x,PC-Lint v8一共延续了超过7个年头,估计不是考虑到26个英文字母的后缀都即将耗尽,Gimpel还舍不得用v9的版本号……

粗略看了一下v9的发布说明,相比v8确实有长足的进步(其实我想说的是,v8实在是发展的太落后了……)。不错,很好,很强大!

·终于加入了众望所归的线程分析,可检查锁使用的正确性以及可能缺少锁保护的变量。不过说实话我对这个特性尚持保留态度,因为多线程竞争分析在C/C++中是一个相当复杂的技术,还是等到试用之后再作评论。

·通过预编译头大幅提升复杂项目的检查速度。早该这么做了,PC-Lint对大型工程的检查速度实在不敢恭维。

·栈空间使用统计,可以汇总出单个应用的最大栈空间需求,只要程序中不存在递归并且是具有流程确定性的。赞一下这个功能,在嵌入式开发中尤其实用!

继续阅读PC-Lint终于迎来了9.0版本

C语言小技巧:带扫尾工作的宏

前两天为了在C下编写一个类似Erlang式消息传递的框架,需要定义一个receive宏,使得coroutine处理函数的编写可以类似这样:

int foo()
{
    ...
    receive(msg)
    {
        // Deal with the message
    }
    ...
    receive(msg)
    {
        // Deal with another message
    }
    ...
}

因为foo()函数以coroutine方式执行,所以消息的及时释放就显得尤为重要了,receive()之后紧接的代码块就是这个消息的生存周期,完成之后需要立即对消息进行释放。这就对receive宏的编写提出了一个特别的要求:包含扫尾工作。

继续阅读C语言小技巧:带扫尾工作的宏

C语言小技巧:编译期ASSERT

众所周知,ASSERT一般用于检查运行期的必备条件,它对编译过程没有任何影响,也不能在编译时阻止潜藏的错误。

常见的编译期ASSERT手段是使用 #if…#error…#endif 的结构,但由于#if之中的表达式是在预处理过程中计算,所以无法用到一些编译期才能确定的量,比如sizeof(…)。

无意中在Symbian的SDK头文件中发现一个有意思的宏,实现了真正的编译期的ASSERT:(简化整理后)

#define COMPILE_TIME_ASSERT(expr) typedef char assert_type[expr ? 1 : -1]

它完全可以用于包含sizeof()等静态运算符的检查条件,同时,不会生成任何额外的二进制代码,也不依赖于特定的编译器,使用起来非常简单。但需要注意的是,参数expr只能是静态可计算的表达式,当然如果你不慎使用了非常量的表达式,编译器会阻止程序的编译,同样也起到了确保expr为常量的效果。

运用GDB进行UT/ST的小经验

用惯了VC/Eclipse图形化的程序调试界面后,要适应GDB这种“回归淳朴”的命令行方式,确实需要一些时间。不过当你熟悉了GDB的高级用法后,才能真正体会到程序调试那种随心所欲,尽在掌握的酣畅感。

最近一段时间用GDB作代码测试,积累了一些小小经验,希望对尚未熟悉GDB的朋友有所帮助。(本文以C语言为例说明相应的用法,其它语言可参考GDB帮助文档中对其的支持说明)

业界比较专业的UT(Unit Test,单元测试)工具很多,所以通常不必直接用GDB进行UT,但使用这些专业工具前往往需要花大力气配置环境,编译驱动等,若对于一个小项目,则比直接使用GDB作UT麻烦多了。所以,小项目往往可以借助GDB进行UT/ST合一的测试,效率提升是非常可观的。

ST(System Test,系统测试)一般需要尽可能的逼近实际运行环境,所以应尽量避免或减少对代码有直接介入的工具。这时以GDB作为测试/调试手段就非常实用了。

继续阅读运用GDB进行UT/ST的小经验

当PC-Lint遇上Symbian

PC-Lint是一款强大的C/C++程序检查工具,毫不夸张地说,如果编译器能为你发现20%的程序缺陷,那么PC-Lint至少还能为你发现余下的65%。(最后15%还是留给你自己去排查吧,机器始终是无法取代人脑的~)

可是,当PC-Lint遇上Symbian,就像那法力无边的如来佛遇上了刁钻难缠的孙悟空,也常常拿它没有办法。如今咱可是和谐社会了,怎么说也不能一怒之下就将孙猴儿打下五指山,落的个百年不得翻身吧。为了让两位大爷和平共处,我这观世音也只好费力的来调解调解了。

首先,在下面的地址取得Symbian官方提供的Lint配置文件:
http://www.symbian.com/developer/techlib/v9.2docs/doc_source/faqsdk/faq_0449.html
(如果官方的链接无法下载,请[点击这里]下载其副本)

借助官方的配置文件,PC-Lint已经能够识别大部分的Symbian程序代码。但实践中遇到的一些Lint提示仍然是这份97年之后再也没更新过的配置文件所能应付的。在这里,我补充一些自己总结的额外规则,提供给大家参考:

-D_UNICODE

-e1774			// Disable dynamic_cast
-emacro(717, *)		// Ignore do{...} while(0) in macros
-emacro(???, _LIT)
-emacro(???, _L)
-function( exit, User::Leave, User::LeaveNoMemory )
-function( __assert, User::LeaveIfError )

至于TRAP/TRAPD所产生的“Warning 655”,始终未能找到有效的消除方法。(当然,最坏的情况下你也可以加上括号以迁就PC-Lint的智商……)

Nokia Carbide.C++ 1.2

Nokia终于推出了新版本的Carbide.C++,今天装上试用了一下,感觉变化真的非常大。

首先是兼容性的改善,1.2版终于可以正常导入并识别Symbian 9的mmp格式,不必像1.1中导入之后还得手动修改大量的编译设置。我在导入FontRouter2之后,没有碰到任何障碍,一次编译成功!

其次是速度的优化,虽然Java故有的性能问题并没有得到明显改善,但编译、Index和启动模拟器的速度则有较大幅度的提升,终于不用忍受每次编译时的漫长等待了。

其它改善还在摸索中,总的来说1.1版给人的印象顶多算是一个充斥着bug的pre-Beta版本,而1.2才终于让人觉得稳重了一些。 (:

变参在GCC(PowerPC)上的实现

Keywords: 变参,variable arguments, va_start, va_arg, va_end, GCC, PowerPC, ppc

  花了两天时间定位的一个变参死机问题,结果查出来是传递变参的两个模块所用编译环境的Tornado版本不一致。虽然结果让我很无语,不过此间倒是第一次透彻的了解了变参在GCC(PowerPC)上的实现,一点心得暂记于此。

继续阅读变参在GCC(PowerPC)上的实现