c++代码在不同编译器之间的移植的小故事 - 循环变量
2011-03-06 18:04
417 查看
刚开始工作的时候,加入到一个c++开发小组。当时整个项目组的任务是把VC下面的代码移植到Linux下面。在修改好了makefile文件之后,我80%的时间是在处理一个很简单的问题: 修改循环变量。在2000年左右,VC6是当时用得最多的c++编译器。但是VC6有很多不兼容的一些问题。很多在gcc下面能成功编译的代码,到了vc6下面会报一堆错误。 最麻烦的莫过如此如下一段代码:
如果是今年,这段代码在几乎所有的编译器上都没有问题。但是在VC6上,编译器认为变量i被重复定义了。这可是个大麻烦,因为当时整个系统的代码量达到了十万多行。 另外,代码是很多前辈修修改改的杰作, 到了我“这一代”,估计已经没有人完全能读懂所有的代码了。 这样,修改就变成一件非常细心的事情。当然,改动起来也很容易,最简单的方案就是把循环变量提出来,一了百了。
看起来小菜一碟,这个问题得到解决. 不过,碰到了某个函数里面i已经作为了一个局部变量的时候,容易出大问题。
例如
显然,i的输出会变得大不一样。早期的c编译器, 要求把变量的声明放在函数开始的地方。这位程序员用惯了古老的c编译器,早早就定义了i, 如果按照原有代码,for循环不会对之前定义的局部变量i造成影响。运行也不会有什么问题。 但为了移植到windows, 去迎合VC6编译器的这个缺陷。 一个不严谨的改动导致了意想不到的问题问题。 这个模块是为了一个电信计费系统用的,一点错也容不得。幸运的是,改完之后的回归测试发现了这个问题,不然会酿成大祸。当然,也有更安全的方案去解决这个问题,那就是在每个for循环外面在加上一对{}. 就像这样
看起来很不雅观,但是这种改动却是”安全“
小结: ”先使程序能工作,让后对他们进行移植“ 是一个正常的思维定势,但软件到了开发后期在考虑移植会有许多意向不到的问题和导致更多的工作量。还不如事先略作规划。
for(int i=0; i<a.size(); i++) {//… }; for(int i=0; i<b.size(); i++) {//… }
如果是今年,这段代码在几乎所有的编译器上都没有问题。但是在VC6上,编译器认为变量i被重复定义了。这可是个大麻烦,因为当时整个系统的代码量达到了十万多行。 另外,代码是很多前辈修修改改的杰作, 到了我“这一代”,估计已经没有人完全能读懂所有的代码了。 这样,修改就变成一件非常细心的事情。当然,改动起来也很容易,最简单的方案就是把循环变量提出来,一了百了。
int i; for(i=0; i<a.size(); i++) {//… }; for(i=0; i<b.size(); i++) {//… }
看起来小菜一碟,这个问题得到解决. 不过,碰到了某个函数里面i已经作为了一个局部变量的时候,容易出大问题。
例如
int i =0; for(i=0, i<a,size(); i++) //原来的是for(int i=0 { //... } //... 很多行以后 while(isValid(b[i]) i++; Output(i);
显然,i的输出会变得大不一样。早期的c编译器, 要求把变量的声明放在函数开始的地方。这位程序员用惯了古老的c编译器,早早就定义了i, 如果按照原有代码,for循环不会对之前定义的局部变量i造成影响。运行也不会有什么问题。 但为了移植到windows, 去迎合VC6编译器的这个缺陷。 一个不严谨的改动导致了意想不到的问题问题。 这个模块是为了一个电信计费系统用的,一点错也容不得。幸运的是,改完之后的回归测试发现了这个问题,不然会酿成大祸。当然,也有更安全的方案去解决这个问题,那就是在每个for循环外面在加上一对{}. 就像这样
{for (int i=0; i<a.size(); i++) { //... }}
看起来很不雅观,但是这种改动却是”安全“
小结: ”先使程序能工作,让后对他们进行移植“ 是一个正常的思维定势,但软件到了开发后期在考虑移植会有许多意向不到的问题和导致更多的工作量。还不如事先略作规划。
相关文章推荐
- C++不同类型数值变量之间相互赋值的规则
- warning C4407: 在指向成员表示形式的不同指针之间进行转换,编译器可能生成不正确的代码
- 正则式代码转换程序,用于cocos2d-x不同版本之间程序移植。
- VS6.0和VS2005开发C++时,二者的编译器之间令人不习惯的不同
- warning C4407: 在指向成员表示形式的不同指针之间进行转换,编译器可能生成不正确的代码
- warning C4407: 在指向成员表示形式的不同指针之间进行转换,编译器可能生成不正确的代码
- C++中全局变量的编译器初始化值
- c++基础:普通变量初始化与类内初始值初始化的不同
- 编写可移植的C++ 模板代码
- 移植C/C++程序到不同平台时需要留意的地方
- C/C++的64位整型在不同编译器下的比较
- java 同一个类下的不同方法的变量之间的引用
- 解决VC6和VC2008的for循环变量作用域不同问题的一个方法
- C++中有关volatile关键字的作用--阻止编译器将其变量优化缓存到寄存器(和线程相关)(转自百度)
- C/C++的64位整型 不同编译器间的比较
- c++中各类型成员变量的不同方式的初始化
- Qt与C#之间的代码移植细节--慢慢的
- C++(8):指向不同类型变量或函数的pointer
- [转]跨平台的 C++ 代码移植要点
- var和let定义变量在循环中的不同