已经是3月19日了,突然想到自己3月份还未曾发表一篇文章,于是想写点什么东西,技术含量高的文章一时也写不出,于是打算拿一些Skills或者Tips类的文章来凑凑数,这篇文章属于此列。
最近写了一个程序,给公司的仪器使用的,完成后我把代码放在svn中,Firmware组的Manager似乎对此代码比较感兴趣,就checkout了一份,几天后他告诉我在VC2005下编译有问题,我觉得奇怪,我写的代码通常都是Least dependence,应该不会存在编译不过的问题啊,但考虑到我是用VC6写的,转换到VC2005上会有些问题。
观察后发现是一个函数参数转换上出了差错,我把这个差错用简单的代码重现了出来:
#include "stdafx.h"
void TestFun(const char* &sz)
{
static char bbb[10];
sz = bbb;
}
void main(int argc, char* argv[])
{
char *aaa = "abcdefg";
TestFun(aaa);
}
这个在VC6下编译,运行都是没有任何问题的,这段代码的意思是把字符指针aaa传给TestFun,由TestFun给aaa重新赋值,使得aaa指向另一个地址,aaa本身可以改变,但我不希望在TestFun中aaa指向的地址的内容会发生改变,所以TestFun的参数中有个const修饰,如果TestFun中出现类似sz[0]=40;这样的语句,编译是肯定报错的。
OK,同样的代码,到了VC2005就编译不过了,错误提示如下:
error C2664: 'TestFun' : cannot convert parameter 1 from 'char *' to 'const char *&'
这是个参数转换的错误,修正这个错误有多种办法,最简单的方法是给aaa加上const修饰,变为:
const char *aaa = "abcdefg";
这样改有个弊病,TestFun之后我还需类似aaa[0]=41;这样的操作的话就不行了,必须这样:
const_cast<char &>(aaa[0]) = 40;
很别扭。另一种修改的办法是TestFun的参数中的const修饰去掉,这样就简单一些。但这就没法防止aaa指向的地址的内容在TestFun中受到不经意的修改。VC6和VC2005系出同门,却在此产生了分歧。我估计多数人会支持VC2005,因为它新嘛,但知道微软为什么要这样改么?我是不太明白,我支持的是VC6,因为这种做法完全符合C++的标准,为什么要作这个转换限制呢?
我那个程序修正了这个之后还是编译通不过,不过不是这里的原因,是由于Resource Link的原因,我居然还手动修改了rc文件才编译过了,这里且略过不提。
BTW:我还继续在用VC6,没什么,因为速度快,我讨厌运行“贼”慢的程序。