VC6向VC9 移植时常见BUG4

来源:百度文库 编辑:神马文学网 时间:2024/05/23 19:12:38
在VC6的编译器中,这样的代码是没有问题的,因为VC6的编译器为了兼容旧的Microsoft C/C++编译器,没有严格按照C++标准执行,但是从VC7开始,VC的编译器开始遵守C++标准,所以就会出现“变量i没有定义的错误”。解决的方法也很简单,按照Jim Hyslop 和 Herb Sutter的经典对话系列的第四篇中的方法,改成如下就可以了:
int i;
for(i = 0; i < 120; i++)
十、字符串函数的返回值问题
strchr(_tcschr)、strpbrk(_tcspbrk ??)、strrchr(_tcsrchr)和strstr(_tcsstr)这四个函数在VC6的CRT库中定义的返回值都是char *(TCHAR *),所以以前的代码通常是这样使用的:
TCHAR *cp = _tcschr( pszPath, _T('\') );
//使用*cp,可以通过cp指针修改pszPath的内容
这其实是一个“漏洞”,因为如果pszPath是const char(TCHAR) *字符串,那么就表示它不希望修改字符串的内容,但是调用strchr(_tcschr)函数后就可以通过cp指针修改其内容了,这岂不荒谬?所有在新版本的CRT库中,这几个函数的返回值都改成const char *,这就会导致上面的代码产生编译错误。建议的修改方式是改成如下方式:
const TCHAR *cp = _tcschr( pszPath, _T('\') );
//不能再通过cp指针修改pszPath的内容
但是这样修改可能对代码的影响比较大,比如下面的代码:
TCHAR buf[256]; //局部缓冲区
......
TCHAR *cp = _tcschr( buf, _T('\') );
//作为局部缓冲区(非const),希望通过cp修改buf的内容
这种情况怎么办呢?对了,C++还有个const_cast操作符,这时就可以排上用场了:
TCHAR *cp = const_char(_tcschr( buf, _T('\') ));
不过上面的方法要慎用,除非确定buf是非const的,否则最好老老实实地修改代码。
十一、类成员函数指针做为函数参数的“C3867”错误
考察下面的代码,CWzWindowsHook类的构造函数使用一个该类的成员函数指针,这样构造对象时可以选择消息过滤的handler,可以是MouseMsgFilter,也可以是KeyboardMsgFilter:
typedef BOOL (CWzWindowsHook::*FILTERPROC)(WPARAM wParam, LPARAM lParam);
// A hook used in customization sheet to filter keyboard/mouse events
class CWzWindowsHook
{
private:
FILTERPROC m_pFilter;
BOOL MouseMsgFilter(WPARAM wParam, LPARAM lParam);
BOOL KeyboardMsgFilter(WPARAM wParam, LPARAM lParam);
public:
CWzWindowsHook(FILTERPROC pFilter) : m_pFilter(pFilter)
旧的遗留代码存在这样的用法:
CWzWindowsHook mouseHooker(CWzWindowsHook::MouseMsgFilter);
在VC6的编译器下编译可能没有问题,但是在VC9的编译器下编译会有如下报错:
f:project.....WzWindowsHook.cpp(272) : error C3867: 'CWzWindowsHook::MouseMsgFilter': function call missing argument list; use '&CWzWindowsHook::MouseMsgFilter' to create a pointer to member
虽然C++从C继承来了函数名即是函数地址的语法规则,但是根据C++的标准,类成员函数的指针仍然需要一个取地址符“&”。解决方法很简单,按照提示改成如下代码即可:
CWzWindowsHook mouseHooker(&CWzWindowsHook::MouseMsgFilter);
十二、wchar_t *类型与USHORT *的转换错误
VC6的编译器不支持wchar_t数据类型,wchar_t实际上被定义成unsigned short,VC9的编译器已经支持wchar_t为内置数据类型,但是由一个编译选项控制,这个选项默认是打开的,也就是将wchar_t作为编译器的内置数据类型。但是OLECHAR和WCHAR的定义仍然是unsigned short,在VC6的编译环境中,两者的指针都是USHORT *,相互赋值和做为函数参数传递没有问题,但是如果wchar_t作为编译器的内置数据类型,那就意味着wchar_t *与OLECHAR *或WCHAR *是两种不同类型的指针,相互赋值就会报编译错误,下面的信息就是一个典型的错误输出:
f:project.....shellpidl.cpp(290) : error C2664: 'MultiByteToWideChar' : cannot convert parameter 5 from 'USHORT *' to 'LPWSTR'
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
解决的方法就是使用C++的reinterpret_cast操作符或使用C-style强制转换,当然也可以在项目属性设置中关闭前面提到的那个选项(这个偶美试过,不知道会不会有其它问题)。