2011年3月31日

Google Cpp Style Guide 1.1 #define保护:里面没写清楚对svn或者git管理项目源代码的假设

=============================
1.1. #define 保护
Tip 所有头文件都应该使用 #define 防止头文件被多重包含, 命名格式当是: <PROJECT>_<PATH>_<FILE>_H_
为保证唯一性, 头文件的命名应该依据所在项目源代码树的全路径. 例如, 项目 foo 中的头文件 foo/src/bar/baz.h 可按如下方式保护:
#ifndef FOO_BAR_BAZ_H_
#define FOO_BAR_BAZ_H_
xxxxx

Google Cpp Style Guide 1.1 #define保护:里面没写清楚对svn或者git管理项目源代码的假设

------------------------------------------------------------
1.1. #define 保护
Tip 所有头文件都应该使用 #define 防止头文件被多重包含, 命名格式当是: <PROJECT>_<PATH>_<FILE>_H_
为保证唯一性, 头文件的命名应该依据所在项目源代码树的全路径. 例如, 项目 foo 中的头文件 foo/src/bar/baz.h 可按如下方式保护:
#ifndef FOO_BAR_BAZ_H_
#define FOO_BAR_BAZ_H_

初步接触Google Style和Cpplint

试着看了一下Google Style的C++编码规范,先随手写了一个最简单的程序来试试Cpplit。代码如下
------------------------------------
#include <iostream>

using namespace std;

int main() {
    cout << "Hello World!" << endl;
    return 0;
}
------------------------------------
运行指令
------------------------------------
g++ main.cpp -o main
./main
------------------------------------
得到结果
------------------------------------
Hello World!

------------------------------------
运行Cpplint,得到的结果如下
------------------------------------
main.cpp:0:  No copyright message found.  You should have a line: "Copyright [year] <Copyright Owner>"  [legal/copyright] [5]
main.cpp:1:  Streams are highly discouraged.  [readability/streams] [3]
main.cpp:3:  Do not use namespace using-directives.  Use using-declarations instead.  [build/namespaces] [5]
Done processing main.cpp
Total errors found: 3
------------------------------------
第一条说我没有版权信息,第二条没看懂,第三条说的是不能用std全部空间,建议使用具体用到的函数。

仔细上网查了半天,终于弄懂了第二条是什么意思。

------------------------------------------
5.9. 流
Tip 只在记录日志时使用流.
定义: 流用来替代 printf() 和 scanf().
优点: 有了流, 在打印时不需要关心对象的类型. 不用担心格式化字符串与参数列表不匹配 (虽然在 gcc 中使用 printf 也不存在这个问题). 流的构造和析构函数会自动打开和关闭对应的文件.
缺点: 流使得 pread() 等功能函数很难执行. 如果不使用 printf 风格的格式化字符串, 某些格式化操作 (尤其是常用的格式字符串 %.*s) 用流处理性能是很低的. 流不支持字符串操作符重新排序 (%1s), 而这一点对于软件国际化很有用.
结论: 不要使用流, 除非是日志接口需要. 使用 printf 之类的代替.

使用流还有很多利弊, 但代码一致性胜过一切. 不要在代码中使用流.

拓展讨论:
对这一条规则存在一些争论, 这儿给出点深层次原因. 回想一下唯一性原则 (Only One Way): 我们希望在任何时候都只使用一种确定的 I/O 类型, 使代码在所有 I/O 处都保持一致. 因此, 我们不希望用户来决定是使用流还是 printf + read/write. 相反, 我们应该决定到底用哪一种方式. 把日志作为特例是因为日志是一个非常独特的应用, 还有一些是历史原因.

流的支持者们主张流是不二之选, 但观点并不是那么清晰有力. 他们指出的流的每个优势也都是其劣势. 流最大的优势是在输出时不需要关心打印对象的类型. 这是一个亮点. 同时, 也是一个不足: 你很容易用错类型, 而编译器不会报警. 使用流时容易造成的这类错误:
cout << this;   // Prints the address
cout << *this;  // Prints the contents
由于 << 被重载, 编译器不会报错. 就因为这一点我们反对使用操作符重载.

有人说 printf 的格式化丑陋不堪, 易读性差, 但流也好不到哪儿去. 看看下面两段代码吧, 实现相同的功能, 哪个更清晰?
cerr << "Error connecting to '" << foo->bar()->hostname.first
     << ":" << foo->bar()->hostname.second << ": " << strerror(errno);

fprintf(stderr, "Error connecting to '%s:%u: %s",
        foo->bar()->hostname.first, foo->bar()->hostname.second,
        strerror(errno));
你可能会说, “把流封装一下就会比较好了”, 这儿可以, 其他地方呢? 而且不要忘了, 我们的目标是使语言更紧凑, 而不是添加一些别人需要学习的新装备.

每一种方式都是各有利弊, “没有最好, 只有更适合”. 简单性原则告诫我们必须从中选择其一, 最后大多数决定采用 printf + read/write.
------------------------------------------

最终改好的程序如下,Cpplint能通过,g++也能通过
------------------------------------------
// Copyright 2011 Bill_Lang
#include <cstdio>
int main() {
    printf("Hello World!");
    return 0;
}
------------------------------------------

直接看Google Style会一会儿就烦了,但是配合着使用Cpplint,还是挺有乐趣的。看来还能帮助自己提高C++编程的实际水平。

推荐朋友们也玩玩这个。

2011年3月30日

2011年3月简述

对照年度总结

每周精读一篇论文:这个月项目压的太紧,居然一篇也没读!!
锻炼:打了三次羽毛球,还有一次是球馆在装修;参加了一次台球厅的活动,斯诺克不好打,但更有意思
读书:这月读书只完成一本书(《大学,究竟读什么》)的1/5。读完大学再看这本书,感觉挺有意思
工作:今天上午顺利完成计划内的项目发布,保持了三个月升级一次的记录,感谢折腾我的Bug们,两个完整的周末都搭进去了
生活:师弟正华实习结束回哈尔滨去了,新加坡的芒果和榴莲开始大面积上市了,好吃但不能多吃

下月主要改进:项目告一段落,开始读论文,读书,读代码,读PPT

2011年3月26日

鬼魅般的Bug吃掉了我的榴莲

一周来,不停的和各种Bug斡旋着,三日前解决了一个重大的GBK里GB2312外汉字的不能翻译的问题,算是小小进步。

三日来被一个鬼魅般的Bug萦绕着,这个Bug飘忽不定,在一个确定的配置下在确定的句子上翻译时就会Crash掉,原因据GDB说是内存重复释放。但换一个配置就会在另外的特定句子上Crash掉。挖地三尺,都快到六尺了还没有搞定。

昨晚太太买回两盒刚上市的新鲜榴莲犒劳我,吃完一盒打算另一盒放到冰箱。结果拎着垃圾袋和另一盒榴莲去楼道口仍的时候,竟然将垃圾袋和另一盒榴莲随手同时扔进了那种直接通往地下的垃圾通道。瞬间就意识到"问题的严重性"。太太听了后,过了一会儿才算谅解。

仔细想想,应该算是这个鬼魅般的Bug吃掉了我的榴莲。Bug还得继续调啊。送你榴莲了,让我Fix掉这个Bug吧~~

2011年3月10日

折纸是艺术,也是科学:看Robert Lang的TED演讲有感

昨天在Gtalk上写的状态是“折纸和剪纸都是一张纸的艺术世界”,yu fei朋友回复的内容是“让我突然想起前一阵子看的一个TED的视频:http://www.ted.com/talks/robert_lang_folds_way_new_origami.html

折腾了半天,看完了这个TED视频。谢谢yu fei的推荐,这个TED演讲真不错。Robert Lang是个奇才。折纸是个可以用科学来铸就的艺术,这一点是Robert Lang的这个演讲中能看出来的。他创建的网站也充分的展示了这一点(http://www.langorigami.com/index.php4),按照他发布的TreeMaker软件,几乎能做出模拟任何物体的折纸(http://www.langorigami.com/science/treemaker/treemaker5.php4)。由衷的佩服!

演讲末尾的那个动画展示让人很惊讶,折纸的世界真是神奇。

忽然又想起了电影《三日危情》(http://movie.douban.com/subject/3808604/)里的那段关于教男主角如何越狱的台词。最关键的一句就是要注意观察,尤其是那些异常的细节。从中能发现漏洞。然后充分利用这些异常的漏洞来完成你的壮举。

猜想Robert Lang起初是个折纸迷,后来全身心总结后发现了其中的奥秘并完成了这样一个伟大的软件(Robert戏说,这个软件可以运行在任何平台上,甚至是Windows :)   )。就像视频末尾介绍的几个应用折纸艺术(或者该叫技术)来协助设计一些重要器件那样,折纸艺术真是应用很广啊。

呵呵,一时激动,写了这段文字。一句话的感悟是,做科研或者技术就得注意观察任何异常,并不断总结,达到艺术与技术的融合。观察与思考,得出自己的结论很重要!

2011年3月1日

2011年2月简述

对照年度总结

每周精读一篇论文:这条完成得很不好,只精读了一篇
锻炼:每周都参加了羽毛球活动,额外的两次锻炼也在住处的小区保质保量完成(主要是跳绳,仰卧起坐加双杠)
读书:看完非专业书籍《禅里禅外悟人生》和《大学毕业等于零》,在读专业书籍《Essential C++》
工作:进展顺利,主要围绕语料整理和新的toolkit的封装
生活:新加坡最北边的地段比市区凉快,也更安静

下月主要改进:上班时需全身心工作,下班回家后全身心休息