在我们的开发中,跨平台的需求越来越强烈,如何保持C/C++代码能在多个平台上编译,是一个比较值得研究的问题。关于跨平台的文章网上很多,跨平台的库网上也很多。那么我从自己的跨平台开发经验谈一谈自己的心得,希望对大家能够起到一定的作用。主要涉及到Windows和linux两个操作系统。
1、 关于路径和头文件路径分隔符的问题
在Windows中,正斜杠和反斜杠都可以,但是在Linux中,只能是/。
在Windows中,路径大小写无所谓,在Linux中严格区分大小写。
2、 char的问题
如果考虑跨平台,需要明确指定是signed或者unsigned,因为不同平台直接声明char,会导致signed或者unsigned的不确定性。
3、 关于宽字符的问题。
在Windows中,wchar_t占两个字节,Linux中占四个字节,但是在Linux可以指定两个字节,这样也会造成一个问题,就是某些第三方库中wchar_t可能只指定四个字节的,这样就会导致不兼容。
4、 Linux里面没有stricmp函数,在Linux下面是strcasecmp函数比较字符串。
5、 与平台相关的调用尽量用宏隔离开来,一般用不同的目录代表不同平台,BOOST、OGRE等是这样做,也可以再一个类或者文件中,这样会导致到处都是操作系统和编译器相关宏的定义。
6、 关于头文件包含
在Windows下某些C标准库的头文件不用显式包含,但是在linux下需要显式包含。所以在.c和.cpp文件中尽量包含这个文件中需要的头文件。
7、 注意机器大尾端和小尾端的区别
大小尾端对文件的读写会有很大影响,要编写跨平台c++程序,大小尾端是必须要考虑的问题。比如,你在大尾端机器上写了一个文件,然后在小尾端机器上读取,那么结果肯定是错误的,所以,我们设计文件格式时,都需要规定文件是大尾端存储还是小尾端存储,或者一个文件中规定某些部分是大尾端某些部分是小尾端。
8、 尽量只使用STL较早出现的函数或类
较早出现的东西相对来说比较稳定,STL的各个实现基本上都会有实现,这样跨平台的时候可以兼容多个平台。
9、 使用std::exception时需要注意,LINUX下是不支持抛出异常的,如果继承自标准库的异常类写自己的异常类的时候,在Linux下,子类的析构函数中就需要表明不抛出异常,所以析构函数后面加上throw()就可以了。
10、当继承模板类时。需要谨慎
在自己的代码中,需要继承模板类时,如果需要访问基类模板类的成员函数或者成员变量,前面加上this->。另外,构造函数需要用到基类进行构造时。基类的类型需要需要用该类的类型参数初始化,否则在linux下会提示找不到基类的这个名字。
11、尽量使用标准C和C++的函数以及STL,使用C语言中定义的类型。
12、头文件重复包含的问题
尽量用保卫宏去实现防止头文件的重复包含,很多代码在Windows下直接用#pragma once,这不能保证跨平台需要。
13、关于结构体对齐的问题。
CPU为了简化内存和CPU之间的处理以及加快CPU从内存中取数据的速度,往往都会做一定的对齐,即结构体的各个成员并不是紧凑存储的,往往在成员中间填充一些字节。所以,我们一般不推荐用结构体直接读取和写入数据,这样在不同系统或者计算机之间进行移植时,会出现错误的结果。
14、注意BOM的陷阱(字节顺序标记)
如果你在Windows用记事本创建一个源文件,那么Windows会在文件最前面加上一个BOM标记,即所谓的字节顺序标记,这样的源码在Windows下没问题,但是在Linux下就编译不过,所以需要用其他的文本编辑器或者直接在VS里面创建源文件。Linux下gcc/g++不认带BOM标记的源文件。
15、注意调用函数时的形参类型和函数声明中参数列表的类型不匹配。这里特指有无const或者是否是引用参数。在Windows下的cl编译器没问题,linux下GCC/G++会报错。
16、注意两个尖括号不要连着写。例如std::vector<std::vector<int>> vec;在Windows下这么写完全没问题,那么在linux下就是编译不过,所以linux下可以在连续两个尖括号符号之间留一个空格,即std::vector<std::vector<int> > vec;
其实,这些只是冰山一角,在跨平台C/C++开发上还需要做更多的探索。
转自: http://blog.csdn.net/zhouxuguang236/article/details/45166447