移植工作開始后的第一步就是在目标平台Linux上进行编译,并链接源码。因为须要移植的软件通常并未在Linux平台上编译过,编译的过程可能会遇到非常大的困难。普通情况下,由类型声明引起的编译错误是比較easy修复的。比方Microsoft C/C++的头文件使用__declspec( dllimport/dllexport )来输入和输出DLL函数,在Linux上,把函数声明成extern “C”,或者再结合使用DEF文件,使用对应的链接命令就能够解决这些问题。但困难的地方在于编译器之间存在差异的部分,同一时候这也是可能引起非常多执行时问题的重要因素,读者有必要在開始移植之前就充分了解。在此讲述一些easy被忽略而且后果比較严重的方面。

  以Visual C++ 2003和GCC 4.1.0为例。前者是Windows平台的主流编译器,兼容性良好,可是对C++标准的遵循并不严格。这意味着即使开发人员写出不太符合标准的程序,编译器也可能能容忍。相反的是,GCC对标准的遵循相对严格得多,这样非常easy造成在Windows执行良好的程序,在Linux上却引起意想不到的编译甚至执行时错误。

(1)基本类型大小和结构对齐

  首先是 C/C++语言基本类型的大小,以及对应的结构对齐问题。典型的样例是longkeyword。在Visual C++ 2003下,sizeof(long double)是8,其大小和double一致。可是在GCC 4.1.0上,sizeof(long double)等于12,其大小比double多4。还有一个和大小相关的问题是对齐问题。不同编译器的默认对齐大小是不一样的。普通情况下程序逻辑都跟对齐无关,可是涉及从磁盘或者网络文件里读取结构时(如解析资源),精确的对齐就是必需的。考察以下的程序段:

#include 
struct A

{
char a;
double b;
};

int main()
{
printf("%d %d %d\n", sizeof(long double), 
sizeof(long long), sizeof(A) );
return 0;
}

  上面这段程序在 Visual C++ 2003编译器默认设置下,输出结果为8 8 16;在GCC 4.1.0编译器默认设置下,其输出为12 8 12。从sizeof(A)的大小能够看出,Visual C++ 2003是按8字节对齐的,而gcc是4字节对齐的。这时须要使用#pragma pack预编译指令来改动头文件里的结构声明,或者在执行时调整内存中结构成员的位置。无论採用何种方法,对齐都是须要小心处理的事情。

  一个引起最大麻烦的基本类型是wchar_t。在Visual C/C++ 2003编译器中,wchar_t的大小是2字节,而且能够和unsigned short类型互相赋值。与此关联的一系列Unicode相关函数,比方wcslen,wcscmp等,都接受UTF16格式的Unicode串。在 GCC中,其大小是32位。与此相关的wcslen,wcscmp函数都接受UTF32格式的Unicode串。为此,必须在Linux上开发一套 UTF16接口的wcs系列函数,以保证UTF16的字符串被正确处理。与此同一时候,使用宏定义来替换wchar_tkeyword为unsigned short,以保证函数声明的兼容。

(2)new操作符的出错处理

  还有一个问题是new操作符的出错处理。因为编译器的设置不同,new操作符可能具有不同的行为。考察例如以下的代码段:

#include 
class A
{
public:
void *operator new( size_t size )
{
return NULL;
}
A()
{
printf("Constructor called\n");
a = 0;
}
private:
int a;
};

int main()
{
A *p = new A();
printf("%x\n", p );
return 0;
}

  在Visual C++ 2003中,上面的程序输出0。而GCC 4.1.0编译器的输出结果为:

   Constructor called
   Segmentation fault

  也就是说,Visual C++ 2003的编译器会检查new的返回值,假设返回为空,构造函数就不再执行。可是gcc必须加上–fcheck-new编译參数才具有这一行为:g++ –fcheck-new test.cpp。这样在Linux上上述程序也会输出0。

(3)结构化异常和C++异常

  还有一个更隐蔽的差异存在于异常处理。Visual C++并不遵循异常处理的C++规范。考察例如以下的程序段:

#include 
int main()
{
int* p = NULL;
try
{
*p = 0;
}
catch (...)
{
printf("caught the exception\n");
return 1;
}
return 0;
}

  读者能够自己用 Visual C++ 2003和GCC分别检验这段程序。前者生成的程序在Windows上正常执行,输出caught the exception,然后正常退出。而GCC生成的程序仅仅是输出Segmentation fault。所以在Windows上,catch语句抓住了一个异常。依照C++的标准,唯独使用throw语句,才干产生异常。可是在上面的程序段中, 仅仅是一个简单的赋值语句。原因在于,Visual C++ 2003将C++的异常处理映射成了Windows的结构化异常处理。在上面的语句中,*p = 0将引起一个Windows的异常,Visual C++将它处理成一个C++异常,并进入catch块。在Linux上,因为沒有C++异常发生,程序直接崩溃。

Linux与Windows编译器的区别的更多相关文章

  1. 【转载】LINUX 和 WINDOWS 内核的区别

    LINUX 和 WINDOWS 内核的区别 [声明:欢迎转载,转载请注明出自CU ACCESSORY http://linux.chinaunix.net/bbs/thread-1153868-1-1 ...

  2. 从Docker在Linux和Windows下的区别简单理解Docker的层次结构

    上篇文章我们成功在Windows下安装了Docker,输出了一个简单的Hello World程序.本文中我们将利用Docker已有的云端镜像training/webapp来发布一个简单Python的W ...

  3. 深度剖析Linux与Windows系统的区别

    当我们每个人接触Linux之前,应该先接触的都是windows吧?但我们一般接触Linux后,习惯linux的管理和使用方法后,我们再回过头再来使用windows的时候,内心其实是拒绝的.我们会觉得图 ...

  4. 深度剖析Linux与Windows系统的区别,新手必读!

    当我们每个人接触Linux之前,应该先接触的都是windows吧?但我们一般接触Linux后,习惯linux的管理和使用方法后,我们再回过头再来使用windows的时候,内心其实是拒绝的.我们会觉得图 ...

  5. linux和windows系统的区别

    在21世纪的今天,互联网可以说是当代发展最为迅速的行业,举个很简单的例子,现在的我们不论什么年龄阶层,几乎人手都有一部手机,上面的某博,某音,末手等软件,更是受到多数人的热爱,并且人们不仅仅用其来消遣 ...

  6. linux与Windows使用编译区别及makefile文件编写

    一.Windows与:Linux嵌入式开发区别 Windows下编辑.编译.执行 编辑: sourceInsight:ADS: 编译:指定链接地址,指定链接顺序,编译 执行:烧写到单板再启动 Linu ...

  7. python+unittet在linux与windows使用的区别

    使用python的unittest编写单元测试框架,批量运行测试用例时,如果使用discover时,windows环境下和linux环境下的代码不一样 Windows环境的run.py代码: case ...

  8. 日期在Linux与Windows下的区别

    最近遇到了这个问题,就是相同的代码在Windows与Linux下的日期转换不一致. 原因:时区问题,主要是操作系统与JVM中的时区不同导致的 在网上查了很多处理的方法:最后总结出一条简单粗暴的方法:原 ...

  9. Linux和Windows系统目录结构区别

    Windows目录结构图 Linux目录结构图 我们所有的操作尽量都要在/home/username目录下进行. 快捷进入家目录方式是cd ~.

随机推荐

  1. 关于ionic中几个问题

    第一.每个页面的独立样式style标签不能写在ion-view外面,否则会出现路由问题,建议写在ion-content后面,例如下面的例子中,如果style但在ion-view中的话会出想路由问题,显 ...

  2. django model filter 条件过滤,及多表连接查询、反向查询,某字段的distinct

    1.多表连接查询:当我知道这点的时候顿时觉得django太NX了.  class A(models.Model):    name = models.CharField(u'名称')  class B ...

  3. mysql热备及查询mysql操作日志

    mysql热备 1 查看mysql版本,保证主库低于等于从库 2 主库配置:   A 需要打开支持日志功能:log-bin=mysql-bin   B 提供server-id:server-id=1  ...

  4. PHP结巴程序实现

    <?php $str="我...我要要要...学学学..编编程"; $str=preg_replace('/\./','',$str);//我我要要要学学学编编程 $str= ...

  5. 个人观点,说一下对 PHPCMS 的站点架构的看法

    PHPCMS应该是国内第一家用MVC架构来写开源PHP产品的,我第一次工作上接触到PHPCMS是在两年前.那个时候对MVC还是不理解,然后由于工作须要,须要改动一下PHPCMS的源代码.拿到代码后.我 ...

  6. ABP框架EF6链接Oracle数据库手动迁移

    环境:VS2017 + ABP官方模板(不含Zero) +Oracle 11Gx64DB  + Oracle 11Gx32Client(PLSQL工具访问) 一.Abp项目的下载以及运行 1.创建ab ...

  7. js 正则表达式 取反

    http://www.w3school.com.cn/jsref/jsref_obj_regexp.asp 以匹配中文为例 const test_value = '李钊鸿' if (/[^\u4e00 ...

  8. 更改 Nginx 服务的默认用户

    为什么要更改 Nginx 服务的默认用户:就像更改 ssh 的默认 22 端口一样,增加安全性,Nginx 服务的默认用户是 nobody ,我们更改为 nginx 1.添加 nginx 用户 use ...

  9. ASP.NET MVC自定义视图引擎ViewEngine 创建Model的专属视图

    MVC内置的视图引擎有WebForm view engine和Razor view engine,当然也可以自定义视图引擎ViewEngine. 本文想针对某个Model,自定义该Model的专属视图 ...

  10. React 学习推荐

    推荐学习一.React 入门实例教程     作者: 阮一峰 http://www.ruanyifeng.com/blog/2015/03/react.html 瘳雪峰的Javascript教程 ht ...