VinceYuan

Personal Blog
posts - 12, comments - 37, trackbacks - 0, articles - 0

升级VC7项目到VC8的注意事项

Posted on 2005-12-20 23:34 Vince Yuan 阅读(5472) 评论(17)  编辑 收藏 所属分类: C++

 

在2005年年中的时候,公司就准备转移到Visual Studio 2005上开发产品。本人有幸参与了升级的过程,成功的把30个左右solutions、几百个projects升级到了VC8。由于项目众多,并且项目还在持续开发中,我们的基本策略是让代码同时在VC7.1和VC8下面编译通过,最后再完全转到VC8,链接并运行成功。从总体上说VC8比VC7.1语法上严格且严谨。下面是我的一些经验总结。文中只涉及到编译问题,链接的问题没有包含在内。我的同事Mr Han对此文有巨大贡献,在此非常感谢。
1. 变量作用域
在vc7.1中, 如果一个变量定义在for语句的条件从句中,那么这个变量可以在for之后使用。但Vc8禁止这样,会报告一个C2065错误.

for (int i = 0; i < 10++i)  
{                             
   
//codes here
}

if (i < 10).. //error in Vc8
for (i = 0; i < 5++i) //error in Vc8

解决方法:
在for语句之前声明变量(可保证代码在vc7.1和vc8下同时编译通过)

int i =0;                    
for (i = 0; i < 10++i)
for (i = 0; i < 5++i)

2. 指针和引用的声明
在Vc7.1中, 下面的代码可以编译, 但是vc8会报C4430 错误。(很难想象有些美国程序员竟然这样声明)

const & int a; //error in VC8
const * int b;  //error in VC8
int myfun (const & B); //error in VC8

解决方法:
把* 或&放到类型的后面.

const int& a; 
const int* b;
int myfun (const B&);

3. 默认int类型
在vc7.1中,如果定义一个变量但不声明类型,那么默认为int。VC8不支持。

static i = 0// C4430 error in Vc8 
const i = 0//C4430 error

解决方法:
加上int.

static int i = 0
const int i = 0;

4. 函数的默认返回值类型
同上,VC8不支持把 int 作为默认返回值类

Func()
{return 0;}//error in VC8

解决方法:
明确声明函数返回值类型为 int.

int Func()
{return 0;};

5. 函数地址
Vc7中函数名就是地址。在vc8中,必须要使用&操作符同时写出这个方法的全名(fully qualified name).

class A
{
public:
     
int Test(void);
}
;
void fun(int (A::*test) (void));
int main() 
{
     fun(A::Test);
//C3867 error in VC
     return 0;
}

解决方法:
加上 &.

fun(&A::Test);

6. 隐式类型转换
VC8不允许B* 到const B*&的隐式转换.

class B{};
void fun ( const B* & );//if possible use const B* instead
int main() 
{
*test = new B();
fun (test); 
//error in VC8
return 0;
}

解决方法:
强制转换或函数参数变成const B*。

void fun ( const B*  );

7. 友元方法(Friend function)
VC8不允许声明一个private或protected函数为友元.

class A
{
private:
 
void c();  
}
;
class B
{
  friend 
void A::c(); //C2248 error, c() is invisible to class B.
}
;

解决方法 1:
声明友元类.

class A
{
private:
 
void c();  
}
;
class B
{
  friend 
class A;
}
;

解决方法 2:
把函数声明为public

class A
{
public:
 
void c();  
}
;
class B
{
  friend 
void A::c();
}
;

8. STL的stdext 命名空间
在vc8中,hash_map 和hash_set 被移进了stdext命名空间中.

#include <hash_map>
std::hash_map 
//error in VC8

解决方法:
使用stdext 命名空间.

#include <hash_map>
stdext::hash_map

9. 头文件
许多头文件如fstream.h 和iostream.h在VC8中已经不存在了.

#include <fstream.h> //error in VC8

解决方法:
使用STL.

#include <fstream>

10. Iterator
一些 STL 类, iterators 不再用指针实现

std::vector<DMDetailRow> m_data;
std::vector
<DMDetailRow>::iterator iter = &m_data[rowNum];

解决方法:

std::vector<DMDetailRow>::iterator Iter = m_data.begin() + rowNum;

11. Enum
使用一个Enum的成员时,不要使用enum的名字

enum E
{
  a,b,c
}
;
E e1 
= E::a; //warning in VC8

解决方法:
去掉Enum 的名字.

E e1 = a;

 


 

Feedback

#1楼   回复  引用  查看    

2005-12-21 09:16 by milestone      

#2楼   回复  引用  查看    

2005-12-21 10:02 by 补丁      
为什么会有这些奇怪的写法...-_-!

#3楼   回复  引用  查看    

2005-12-21 19:59 by 沐枫      
去掉Enum 的名字.
E e1 = a;
--------
似乎是倒了回去了。
如果一个Enum的常量命名如果和另一个常量重名,那应该如何呢?比如:
enum E1 {a,b,c};
enum E2 {a,c,e};
E1 e1 = c;
E2 e2 = c;
int v = c;

#4楼   回复  引用  查看    

2005-12-22 09:15 by 装配脑袋      
获取函数指针那一条,是针对成员函数的吧?如果普通函数也得那样就有无数程序面临修改了。。

#5楼   回复  引用    

2005-12-22 17:21 by nicholas in c#[未注册用户]
hi,我是c#新闻组的nicholas,经常看到你在上面热心解决问题,希望能多向你学习:)

#6楼   回复  引用    

2006-05-20 09:35 by qq82916672[未注册用户]
还有一个
再摸板类派生的时候
里面定义typedef
最好加上 typename
如 typedef std::set<T *> MYSET
变成 typedef typename std::set<T *> MYSET

#7楼   回复  引用    

2006-07-04 14:34 by LIN I-FENG[未注册用户]
您好:
感謝您的分享~~
關於第九項
--------
9. 头文件
许多头文件如fstream.h 和iostream.h在VC8中已经不存在了.

#include <fstream.h> //error in VC8
解决方法:
使用STL.
#include <fstream>
--------------------
由於使用STL
需要再加一個

using namespace std;

才會成功

#8楼   回复  引用    

2006-08-18 09:25 by jl[未注册用户]
5. 函数地址

真的搞不懂为什么会有这种写法,非要加上类名,以前的不是很好吗,偶还以为加个& 就OK 了, 加个类名 不伦不类的

#9楼   回复  引用    

2006-08-21 08:57 by VC6[未注册用户]
反正,最好别升级,因为真的有很多的东西要改。
安装boost的说法,VC8使用的是“non-standard library”

#10楼   回复  引用    

2006-08-21 09:09 by VC6[未注册用户]
反正,最好别升级,因为真的有很多的东西要改。
按照boost的说法,VC8使用的是“non-standard "Safe" C++ Library ”(上面说错了)

#11楼[楼主]   回复  引用  查看    

2006-08-22 14:11 by Vince Yuan      
to 装配脑袋 and jl: 这样写的确是针对与成员函数。只能说这样写更加清晰和严谨。

#12楼   回复  引用    

2006-10-30 15:19 by David[匿名][未注册用户]
好,多谢

#13楼   回复  引用    

2007-02-05 14:28 by bt下载[未注册用户]
不错,其实这样反而好,不然vc好多写法不标准,让人难以理解,阅读上有困难

#14楼   回复  引用    

2007-02-05 14:29 by 口爆[未注册用户]
关键是要有一个能自动转换vc2003或vc6的源代码到vc2005的格式就好了。

#15楼   回复  引用    

2007-03-17 16:34 by 可人[未注册用户]
我有一个VC7到VC8下生成不了,提示这样一个错误:

错误 1 错误的结果 -1073741515 (从“D:\Program Files\Microsoft Visual Studio 8\VC\bin\cl.exe”返回)。
怎么办呀?帮帮我呀!

#16楼   回复  引用  查看    

2007-07-21 22:30 by eyye的眼睛      
很多哦
1)CFileDialog dlg(FALSE,0,szDefaultName,4|2,szFilter);//这里的参数顺序
2)CPen pen(PS_SOLID,1,RGB(r,g,b));
CPen* oldpen=pDC->SelectObject(&pen);
改为
HPen pen=CreatePen(PS_SOLID,1,RGB(r,g,b));
pDC->SelectObject(pen);
可以吗?嘿嘿,如果在编译时发生错误,那还是不错的,一直就错也好,关紧就是在你出乎预料的时候.....痛苦!
3)请楼下补充

#17楼   回复  引用    

2007-12-12 11:27 by linusliu[未注册用户]
我把一个vc7项目移植到vc8,其中一个static lib的project setting设置和主项目一样,但是release版的stl map和vector iterator的简单使用会crash,debug版没事,改了一些项目设置之后map没事了,std::vector<xxx> yy; yy.push_back(x);就会crash,有高手知道是怎么会使吗?



发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 301188


相关文章:

相关链接: