一晃眼,原来又有好几个月没有上来。其间写了几个月的javascript,写了几个月的JSP,C++的东西都没有怎么碰过了。
这几天要原来项目的C++代码从32bit的平台移植到64bit的平台。由于以前编写类库的时候已经十分小心,也早有预谋,所以竟然很顺利的全部编译通过,而且-Wall下面都没有任何warning。满心欢喜之下运行了程序。谁知道马上就是一个Segment faul。沮丧之余用gdb跟踪了半天都不知道什么地方的问题。加上valgrind,也是一头雾水,竟然是说标准STL的hash_map的问题……最后在一次跟踪的时候,无意中检查一个指针的初始化值,发现不为空,原因应该就在这里。
翻查代码的上下文,原来指针是跟一个int放在同一个union当中,而union的初始化只初始化了int,而没有初始化指针。在64bit机器的gcc下,int是32bit而指针是64bit,所以就导致指针不为空的现象。所以赶紧把代码中所有union的地方都找出来检查一遍。幸好union这种东西平时不敢多用,也没发现其他的异常。程序重新编译,再运行,没有Segment fault了。
然后再运行了一批unit test。发现其中有几个不能通过,其原因其实也是比较无聊。都是自己不小心之过:
1、sha1的代码copy php的,其中一个php_uint32变量竟然自己写了unigned long,傻瓜致极
2、有个地方保存各种长度整数到文件,因为偷懒,把函数写成了模板,大概就是:
template<typename typeInt>
int write(typeInt n) {
writeToFile( &n, sizeof(n));
}
然后一个不小心,想写个string的长度的时候就变成了: write( str.length() );
str.length()类型是size_t,64bit,与32bit系统的不一样,当然也就出错了。
其实平时都已经很小心,尽量使用static_cast强制转换为特定长度类型的变量再输出的了,偏偏就是漏了一两个地方。