分类 技术志 下的文章

视警告为错误

每当你Build Project代码的时候,如果看到的是满屏的Warning,那么提醒你小心了,不妨看看《高效程序员的45个习惯》中对Warning的态度和处理方式。该书中的第34个习惯讲的是“警告就是错误”! 当然这个“习惯”所阐述的内容并不是这本书首创,在很多经典的传授编程之道的书中也都提到过。

将警告作为错误来处理,说起来容易,可作起来可并不那么简单。这不仅仅只是一个态度的问题,有时候还需要有技术手段或技巧去帮助你完成。《高效程序员的45个习惯》一书的作者也在该习惯所对应的“平衡的艺术”中提到:“如果确实没有应对之策的话,那就不要再浪费更多时间了。但类似这种情况很少发生”。另外他建议应该经常使用编译器的directive(指示器),将一些实在无法避免但又确定不是潜在缺陷的警告进行提示,告知编译器这个地方的警告可以不去理会。

将警告视为错误首先需要的就是勇气,大胆的在你的Makefile中将-Werror赋予给Gcc吧。Gcc则为你提供了一定的技术手段来帮你处理面对无法避免的警告时“左右为难”的情况。

Gcc为我们提供的技术手段就是Pragmas,虽然Gcc手册中建议我们一般情况下不要显式的使用Pragmas,但必要时还是需要这个工具的帮助的。

#pragma directives这个指示器嵌入在源码中,用于在源码编译时给GCC编译器提供一些指示信息。Pragmas有多种分类,这里我们需要的是Diagnostic Pragmas。简单的说,嵌入在源码中的Diagnostic Pragmas给我们提供了如下一些能力:
-> 将某类编译警告按编译错误处理 (如:#pragma GCC diagnostic error "-Wformat")
-> 将某类编译错误按编译警告处理 (如:#pragma GCC diagnostic warning "-Wformat")
-> 忽略某类编译警告 (如:#pragma GCC diagnostic ignored "-Wformat")

Gcc对Diagnostic Pragmas的支持是随着版本进化而逐渐增强的,在gcc 3.4.6版本下Diagnostic Pragmas是不被accepted的,Gcc只accept五类Pragmas;到了gcc 4.4.4版本,Gcc已经可以支持12类Pragmas,这其中就包括Diagnostic Pragmas

通过实际的测试也可以证实以上说明。

e.g.
/* testpragma.c , gcc -Wall testpragma.c */
#include

#pragma GCC diagnostic error "-Wformat"
int main() {
    printf("%d\n", "Diagnostic Pragmas Test");
    return 0;
}

在Sparc Solaris 10上使用gcc 3.4.6编译结果如下:
gcc -Wall testpragma.c
testpragma.c:3: warning: ignoring #pragma GCC diagnostic
testpragma.c: In function `main':
testpragma.c:5: warning: int format, pointer arg (arg 2)
编译器提示忽略了diagnostic pragma指示。

而在Ubuntu 10.04 Gcc 4.4.3版本下编译结果如下:
gcc -Wall testpragma.c
testpragma.c: In function ‘main’:
testpragma.c:5: error: format ‘%d’ expects type ‘int’, but argument 2 has type ‘char *’
编译器正确执行了我们给出的指示^_^。

#pragma directive的作用范围也很好理解:
首先肯定是在同一编译单元范围内有效,在A编译单元中设置的#pragma directive,在B编译单元是无效的。比如我另外编写一个utils.c,其内容如下:
#include

void foo() {
    printf("%d\n", "In another compile unit");
}
我们将utils.c与testpragma.c一起编译,gcc -Wall testpragma.c utils.c,得到的结果是:
testpragma.c: In function ‘main’:
testpragma.c:5: error: format ‘%d’ expects type ‘int’, but argument 2 has type ‘char *’
utils.c: In function ‘foo’:
utils.c:4: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘char *’
在testpragma.c这个编译单元,#pragma directive生效,但是在utils.c这个编译单元并不生效,依旧被诊断为Warning。

其次,在同一个编译单元中,#pragma directive影响的范围是其所在行之后的代码,直到下一次修改针对同样warning option的#pragma被放置。还是举例说明,我们改造一下testpragma.c:
/* testpragma.c */
#include

#pragma GCC diagnostic error "-Wformat"
void foo() {
    printf("%d\n", "Diagnostic Pragmas Scope Test");
}

int main() {
    printf("%d\n", "Diagnostic Pragmas Test");
    return 0;
}
编译命令执行后,Gcc给出的输出结果是:
testpragma.c: In function ‘foo’:
testpragma.c:5: error: format ‘%d’ expects type ‘int’, but argument 2 has type ‘char *’
testpragma.c: In function ‘main’:
testpragma.c:9: error: format ‘%d’ expects type ‘int’, but argument 2 has type ‘char *’
#pragma directive从头置尾一直发挥作用,两个format Warning都被当作Error报告了。

现在我们对main中的问题放松要求,将源码变为:
/* testpragma.c */
#include

#pragma GCC diagnostic error "-Wformat"
void foo() {
    printf("%d\n", "Diagnostic Pragmas Scope Test");
}

#pragma GCC diagnostic ignored "-Wformat"
int main() {
    printf("%d\n", "Diagnostic Pragmas Test");
    return 0;
}
执行编译命令后,Gcc的提示变为:
testpragma.c: In function ‘foo’:
testpragma.c:5: error: format ‘%d’ expects type ‘int’, but argument 2 has type ‘char *’
显然对-Wformat按照Error处理的作用范围仅限于foo这个函数,因为在foo之后我们修改了对-Wformat的指示!

有了编译器的支持,我们将更有信心去养成“视警告为错误”的习惯了。实际工作中,#pragma directive应用应该不多,因为多数情况下的警告都是可以通过正常的代码完善消除掉的。

Ubuntu一周体验

安装Ubuntu已有一周多,无论是在工作单位还是在家里,Ubuntu都作为我的第一OS,Win7基本上处于被打入“冷宫”状态。事实证明对我来说,Ubuntu完全可以取代Windows。

公司提供有线和无线网络两种接入方式,对于致力于追求“理想的无线世界”的我来说,无线接入是我的第一选择。公司的无线接入采用TTLS认证方式,在WinXP和Win7上都有相应的客户端(SecureW2)可供使用,但在Ubuntu上是否有此类客户端我还不知道,咨询了公司的IT服务部门,得到的回答也是“不知道”(想必在公司内部像我这样使用Linux OS的少之又少)。在网络上寻找答案也未果。我之前对无线接入认证那些术语了解甚少,甚至不知道公司采用的是哪种认证方式,但通过SecureW2官方站以及Wikipedia了解到了公司用的是TTLS认证。我无意中打开Ubuntu无线网络连接配置,在连接“编辑”对话框的“无线安全性”标签中居然看到了"隧道TLS"方式,难道Ubuntu内置就支持TTLS?于是我就按照Windows上的配置方式尝试配置了一下,包括密钥协议和内部认证等,点击连接,哇,居然真的连上了!打开Firefox测试了一下,一切OK,问题解决。我将配置方法简单写成了一个Mail发给了公司IT服务部门,希望能为公司其他同遇到这个问题的同事提供一些帮助。

Ubuntu默认采用的是Gnome桌面环境。Gnome近期最受关注的要属计划2011年发布的多次“跳票”的Gnome 3.0了,Gnome 3.0的一个核心组件就是Gnome shell。网上有不少关于Gnome shell的抢鲜体验,其实通过Ubuntu自带的软件中心,大家都可以体验到Gnome Shell,软件中心提供的版本是2.28。安装后使用Alt+F2打开“运行”对话框,输入“gnome-shell –replace”即可启动Gnome shell,也许是之前看过一些抢鲜体验介绍的缘故吧,Gnome shell并未让我感觉有多惊艳。通过Alt+F2,输入debugexit即可退出Gnome shell。因为不是最终稳定版,所以建议不要将之作为默认窗口管理器。

我很喜欢收集电子书,本子里至少有几个G的电子书,不过有很多电子书是chm格式的,Ubuntu下无法打开。安装Wine后似乎自带了一个hh程序用来打开chm电子书,但是我试了一下打开失败。Google了一下,发现有很多Linux下阅读chm的工具,首先试着安装了一下xchm这个工具。工具不大,瞬间安装完毕,试了一本中文chm电子书,打开是没有问题,但是中文字符全部显示为乱码。我找了半天也没有设置中文字符编码的地方。又试了一下纯英文书籍,支持的很好!中文chm不能看,我心里总是不那么舒坦。在Ubuntu中文论坛上又有人介绍chmsee这款小工具,又试了一下,这回中文算是没问题了,就是它了。

前两天尝试安装了一下Macbuntu以体验一下Mac的风格主题界面,结果安装失败,只有登录界面改成Mac形式的了,其他界面主体丝毫没变,问题出在哪里并不清楚,关键是居然没有卸载选项,还搞的我的GVIM一启动就自动退出,并提示:"gtk warning Invalid input string",后来在网上找到了解决方法:
cd /usr/share/vim/vim72/lang
sudo ln -s menu_zh_cn.utf-8.vim menu_zh_cn.utf8.vim
难不成Macbuntu修改了中文区域设置?

今天在奶牛博客上看到Macbuntu版本更新到v2.1了(之前装的是v2.0),抱着侥幸的心理又试一下,这回似乎又进了一步,桌面、Firefox都换成了Mac主题,不过所有的菜单上的中文文字后面都莫名其妙的出现了许多“方格”,十分难看。还好v2.1版本提供uninstall功能,遂回退了。这次回退后Gvim居然也没有问题。

Launchy一直用的很好,但是不知最近安装或卸载了什么软件,每次启动Launchy,都提示Alt+Space的热键已经被占用,但是通过“首选项”->“键盘快捷键”查看,并没有那个程序占用了Alt+Space,诡异的是Launchy也仅仅给个提示,提示后Alt+Space依旧绑定在Launchy上,照用不误!

用wine1.2运行secureCRT,导致secureCRT界面实在是很丑陋!后来干脆都不咋使用secureCRT了,直接在本机编写代码,后来一想:Linux本来就是用来写代码的,还用什么secureCRT啊!

Ubuntu中文论坛上看到10.04版的Ubuntu官方桌面教程中文版已经发布,对于我这样的Ubuntu新手来说浏览一遍官方教程还是大有裨益的。另外发现官方中文Wiki有一页讲解的都是Ubuntu的操作Skills,值得细致品读。

另外找了一本电子书"Ubuntu – Powerful Hacks and Customizations",打算花几天读完它,争取早日摆脱初级选手的这顶帽子^_^。

如发现本站页面被黑,比如:挂载广告、挖矿等恶意代码,请朋友们及时联系我。十分感谢! Go语言第一课 Go语言精进之路1 Go语言精进之路2 Go语言编程指南
商务合作请联系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