2007年9月27日星期四

QT4 和 VS2005 SP1 编译错误 C2244

Author : sanchaji2
Article ID : 94
Audience : Default
Version 1.00
Published Date: 2007/8/7 6:49:30
Reads : 32
一个BUG的修正,可能引入更多BUG的出现不仅仅是教科书上的套话。今天,我在重新编译QT商业版源代码时,就遇到了这样的一个例子。VS2005安装 SP1补丁后,编译QT4源代码(QT v4.2.2版),编译器报告很多模板方面的致命错误,导致编译失败。通过查询网络可知,这是SP1引入的BUG,微软已经发布了修正补丁,您可以在 http://support.microsoft.com/kb/930198 找到详细信息,另外,微软给出了该错误的详细描述,请参考 http://support.microsoft.com/kb/928957

我解决这个问题是通过修改配置文件,使 QT 系统调用 INTEL C++ Compiler 来编译代码避开这个BUG。如果您坚持希望通过MSVC 2005 SP1编译QT源代码,请安装上面提及的补丁,或者参考 thought 的 文章 修改QT源代码。

下面附上,我这里用到的 bin\qtvars.bat,如果您有微软的 KB930198 补丁,希望您能发送到我的电子邮箱 12985462 at QQ dot com ,谢谢!
下面再附上,一份QT与VS2005-SP1的兼容性修正补丁,不用自己修改了!


@echo off
rem
rem This file is generated
rem

echo Setting up a Qt environment...
echo -- QTDIR set to C:\Qt\4.2.2
echo -- Added C:\Qt\4.2.2\bin to PATH
echo -- QMAKESPEC set to win32-icc

set QTDIR=C:\Qt\4.2.2
set PATH=C:\Qt\4.2.2\bin;%PATH%
set QMAKESPEC=win32-icc

if not "%1"=="vsvars" goto END
call "E:\Program Files\Intel\Compiler\C++\9.1\IA32\Bin\ICLVars.bat"
:END

if not "%1"=="vsstart" goto ENDSTARTVS
call "E:\Program Files\Intel\Compiler\C++\9.1\IA32\Bin\ICLVars.bat"
devenv /useenv
:ENDSTARTVS


下面这份修正补丁来自日本一个专门说明这一问题的博客网页: http://ashula.info/mt/d061216_qt4_msvc8_sp1_problem.html


下载: qt4-multi-map-hash-msvc8-sp1.diff
diff -Naur tools_orig/qhash.h tools/qhash.h
--- tools_orig/qhash.h 2006-12-17 03:53:53.406250000 +0900
+++ tools/qhash.h 2006-12-17 05:16:20.921875000 +0900
@@ -848,8 +848,11 @@
QMultiHash() {}
QMultiHash(const QHash &other) : QHash(other) {}

- inline typename QHash::iterator replace(const Key &key, const T &value);
- inline typename QHash::iterator insert(const Key &key, const T &value);
+ // fix for vs2005 SP1
+ // cf. http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=987536&SiteID=1
+ typedef QHash::iterator QHashItr;
+ inline typename QHashItr replace(const Key &key, const T &value);
+ inline typename QHashItr insert(const Key &key, const T &value);

inline QMultiHash &operator+=(const QMultiHash &other)
{ unite(other); return *this; }
@@ -862,11 +865,11 @@
};

template
-Q_INLINE_TEMPLATE Q_TYPENAME QHash::iterator QMultiHash::replace(const Key &akey, const T &avalue)
+Q_INLINE_TEMPLATE Q_TYPENAME QMultiHash::QHashItr QMultiHash::replace(const Key &akey, const T &avalue)
{ return QHash::insert(akey, avalue); }

template
-Q_INLINE_TEMPLATE Q_TYPENAME QHash::iterator QMultiHash::insert(const Key &akey, const T &avalue)
+Q_INLINE_TEMPLATE Q_TYPENAME QMultiHash::QHashItr QMultiHash::insert(const Key &akey, const T &avalue)
{ return QHash::insertMulti(akey, avalue); }


diff -Naur tools_orig/qmap.h tools/qmap.h
--- tools_orig/qmap.h 2006-12-17 03:53:03.437500000 +0900
+++ tools/qmap.h 2006-12-17 05:16:29.984375000 +0900
@@ -890,8 +890,11 @@
QMultiMap() {}
QMultiMap(const QMap &other) : QMap(other) {}

- inline typename QMap::iterator replace(const Key &key, const T &value);
- inline typename QMap::iterator insert(const Key &key, const T &value);
+ // fix for vs2005 SP1
+ // cf. http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=987536&SiteID=1
+ typedef QMap::iterator QMapItr;
+ inline typename QMapItr replace( const Key &key, const T &value );
+ inline typename QMapItr insert( const Key &key, const T &value );

inline QMultiMap &operator+=(const QMultiMap &other)
{ unite(other); return *this; }
@@ -904,11 +907,11 @@
};

template
-Q_INLINE_TEMPLATE Q_TYPENAME QMap::iterator QMultiMap::replace(const Key &akey, const T &avalue)
+Q_INLINE_TEMPLATE Q_TYPENAME QMultiMap::QMapItr QMultiMap::replace(const Key &akey, const T &avalue)
{ return QMap::insert(akey, avalue); }

template
-Q_INLINE_TEMPLATE Q_TYPENAME QMap::iterator QMultiMap::insert(const Key &akey, const T &avalue)
+Q_INLINE_TEMPLATE Q_TYPENAME QMultiMap::QMapItr QMultiMap::insert(const Key &akey, const T &avalue)
{ return QMap::insertMulti(akey, avalue); }

没有评论: