1. 程式人生 > >關於Windows、linux跨平臺的一些建議

關於Windows、linux跨平臺的一些建議

在你做跨平臺開發時,難免會遇到一些因作業系統特性帶來的麻煩。本文集聚部分,並以Windows,linux為目標平臺分析。由於java,Python等語言基本鎖定自家編譯器、IDE,也就沒有C/C++這樣的麻煩了,本文還是以C/C++為主。

1、  關於路徑和標頭檔案路徑分隔符的問題

在Windows中,正斜槓和反斜槓都可以,但是在Linux中,只能是/。

在Windows中,路徑大小寫無所謂,在Linux中嚴格區分大小寫。

2、  關於寬字元的問題。

在Windows中,wchar_t佔兩個位元組,Linux中佔四個位元組,所以儘量用C/C++自帶的字元型別或者第三方跨平臺庫型別如:qchar。

3、  與平臺相關的呼叫

儘量用巨集隔離開來,一般用不同的目錄代表不同平臺,BOOST、OGRE等是這樣做。也可以再一個類或者檔案中,這樣會導致到處都是作業系統和編譯器相關巨集的定義。

4、  關於標頭檔案包含

在Windows下某些C標準庫的標頭檔案不用顯式包含,但是在linux下需要顯式包含。所以在.c和.cpp檔案中儘量包含這個檔案中需要的標頭檔案。

5、  注意機器大尾端和小尾端的區別

大小尾端對檔案的讀寫會有很大影響,要編寫跨平臺c++程式,大小尾端是必須要考慮的問題。比如,你在大尾端機器上寫了一個檔案,然後在小尾端機器上讀取,那麼結果肯定是錯誤的,所以,我們設計檔案格式時,都需要規定檔案是大尾端儲存還是小尾端儲存,或者一個檔案中規定某些部分是大尾端某些部分是小尾端。

6、  使用std::exception時需要注意

LINUX下是不支援丟擲異常的,如果繼承自標準庫的異常類寫自己的異常類的時候,在Linux下,子類的解構函式中就需要表明不丟擲異常,所以解構函式後面加上throw()就可以了。

7、當繼承模板類時需要謹慎

在自己的程式碼中,需要繼承模板類時,如果需要訪問基類模板類的成員函式或者成員變數,前面加上this->。另外,建構函式需要用到基類進行構造時。基類的型別需要需要用該類的型別引數初始化,否則在linux下會提示找不到基類的這個名字。

8、儘量使用標準C和C++的函式以及STL,使用C語言中定義的型別。

9、標頭檔案重複包含的問題

儘量用保衛巨集去實現防止標頭檔案的重複包含,很多程式碼在Windows下直接用#pragma once,這不能保證跨平臺需要。

10、關於結構體對齊的問題。

CPU為了簡化記憶體和CPU之間的處理以及加快CPU從記憶體中取資料的速度,往往都會做一定的對齊,即結構體的各個成員並不是緊湊儲存的,往往在成員中間填充一些位元組。所以,我們一般不推薦用結構體直接讀取和寫入資料,這樣在不同系統或者計算機之間進行移植時,會出現錯誤的結果。

11、注意BOM的陷阱(位元組順序標記)

如果你在Windows用記事本建立一個原始檔,那麼Windows會在檔案最前面加上一個BOM標記,即所謂的位元組順序標記,這樣的原始碼在Windows下沒問題,但是在Linux下就編譯不過,所以需要用其他的文字編輯器或者直接在VS裡面建立原始檔。Linux下gcc/g++不認帶BOM標記的原始檔。

12、結束符問題

Linux/UNIX:    '\n'  (LF)

Mac  :    '\r'   (CR)

DOS(Windows):     '\r\n'  (CR-LF)

所以從linux拷貝檔案到windows,用記事本開啟.h/.cpp時,是沒有換行效果的。

13、注意呼叫函式時的形參型別和函式宣告中引數列表的型別不匹配

這裡特指有無const或者是否是引用引數。在Windows下的cl編譯器沒問題,linux下GCC/G++會報錯。

14、注意兩個尖括號不要連著寫

例如std::vector<std::vector<int>> vec;在Windows下這麼寫完全沒問題,那麼在linux下就是編譯不過,所以linux下可以在連續兩個尖括號符號之間留一個空格,即std::vector<std::vector<int>  > vec;

15、關於庫引用

windows引用動態庫預設從當前目錄取,Linux必須將動態庫新增到庫目錄(註冊系統環境變數)。

16、儘量不要使用內嵌彙編

不同平臺,應該說編譯器,gcc與cl對彙編的語法要求是不一樣的。

17、謹慎使用浮點數

不同硬體、編譯器和編寫程式碼的方式都可以影響結果的精確性。