2011-10-22 95 views
8

在C++中,如果我使用Linux編寫像pong這樣的簡單遊戲,那麼可以在Windows和OSX上編譯相同的代碼嗎?我在哪裏可以告訴它不能被編譯?如何可移植是C++?

+9

這取決於您使用的庫/函數的精確程度以及它們是否適用於所有平臺...... – Yahia

回答

4

您可以閱讀標準 - 如果程序遵循標準,則應在所有具有符合C++標準的編譯器的平臺上進行編譯。

對於您可能使用的第三方庫,通常在文檔中指定平臺可用性。當涉及到GUI時,有跨平臺的選擇(如QT),但你應該問自己 - 我真的想在可移植性方面提供可移植性嗎?有時,最好讓GUI部分是特定於平臺的。

+0

當然,沒有符合標準的編譯器[曾經是一個,但標準已更改],另外許多實現定義的行爲,所以「尊重標準」只是第一步。 –

8

C++是超便攜式的,並且可以在更多的平臺上使用編譯器,而不是您可以動搖的地方。像Java這樣的語言通常被稱爲大規模跨平臺,具有諷刺意味的是,它們實際上通常是用C++或C實現的。這涵蓋了「可移植性」。如果你真的認爲C++是跨平臺的話,那就不是那麼多了:C++標準只定義了一個適合於控制檯IO的IO庫 - 也就是基於文本,所以一旦你想開發某種GUI,你就需要使用GUI框架 - 而GUI框架在歷史上是非常特定於平臺的。 Windows現在有多個「本地」GUI框架 - 微軟提供的C++框架仍然是MFC--它封裝了原生的Win32 API,它是一個C API。 (WPF和WinForms可用於CLR C++)。

Apple Mac的GUI框架被稱爲Cocoa,它是一個Objective-C庫,但它很容易在該開發環境中從C++訪問Objective C。

在Linux上,有GTK +和Qt框架都實際移植到Windows和Apple,所以這些C++框架之一可以解決您的「如何在C++編寫GUI應用程序,一旦在Windows上構建和運行,蘋果mac和linux「。

當然,很難將Qt視爲嚴格的C++ - Qt爲信號和插槽定義了一個特殊的標記,它需要預編譯編譯步驟。

+1

如果您需要非ASCII字符,即使文本I/O也很難做到可移植。 – dan04

+3

在Java中進行挖掘是因爲它是用C++實現的,是一種紅鯡魚。 Perl,Python和Ruby都是用C語言編寫的,但它們更具可移植性,C語言仍然是跨平臺代碼的噩夢。 – Schwern

+0

還有一個支持編譯器,雖然搖動不是原子的,你需要觀看內存的使用。 – ssube

1

如果您正在考慮從Linux移植到Windows,使用OPENGL作爲圖形部分,您可以自由地在兩個操作系統上運行程序,只要您不使用任何系統特定的功能即可。

12

你有三個主要的可移植性障礙。

第一個也是最簡單的,就是編寫所有目標編譯器都能理解的C++代碼。注意:這與編寫C++標準不同。 「寫入標準」的問題始於:哪個標準?你有C++98, C++03, C++TR1 or C++11?這些都是對C++的修改,而使用不太兼容的編譯器的新版本可能會更新。 C++非常大,實際上你所希望的最好的就是具有C++ 03特性的C++ 98。

編譯器全部都添加了自己的擴展名,而且在不知不覺中使用它們都很容易。編寫標準而不是編譯器文檔是明智的選擇。一些編譯器有一個「嚴格」模式,他們將關閉所有擴展。在編譯器中進行初級開發是最明智的選擇,它具有最嚴格的規範和最佳的標準遵從性。 gcc-Wstrict系列標誌打開嚴格的警告。 -ansi將刪除與標準衝突的擴展名。 -std=c++98將告訴編譯器針對C++ 98標準工作並刪除GNU C++擴展。

考慮到這一點,爲了保持理智,您必須將自己限制在少數編譯器中。即使爲多個編譯器編寫一個相對簡單的C庫也很困難。幸運的是,Linux和OS X都使用gcc。 Windows有Visual C++,但是當涉及到兼容性(與標準或其他標準兼容)時,不同的版本更像是一個爭吵的家族,而不是單個編譯器,所以你必須選擇一個或兩個版本來支持。或者,您可以使用gcc衍生的編譯器環境之一,如MinGW

接下來是您的圖形和聲音庫。它不僅僅是跨平臺的,它必須在所有平臺上看起來不錯並且速度很快。這幾天有很多的可能性,Simple DirectMedia Layer是其中之一。你必須選擇你想要編碼的級別。你想要詳細的控制嗎?或者你想要一個引擎來照顧事物? There's an existing answer for this所以我不會詳談。一定要選擇一個致力於跨平臺的人,而不僅僅是碰巧工作。圖形庫中的兼容性錯誤可以讓您的項目快速下沉。

最後,操作系統之間存在着簡單的不兼容問題。 POSIX合規已經走過了一段很長的路,幸運的是,Linux和OS X都是Unix下的Unix,但Windows始終是個怪人。可能會咬你的東西大多與文件系統有關。這裏是屈指可數:

  • 文件系統佈局
  • 文件路徑語法(如C:\富\酒吧VS /富/條)
  • Mandatory Windows file locking
  • 不同的文件權限系統
  • 不同的車型進程間通信(即分叉,共享內存等...)
  • 不同的線程模型(您的圖形庫應該平滑掉)

你有它。真是一團糟,對吧?跨平臺編程既是一種精神狀態,也是一種技術目的。它需要一些奉獻和額外的時間。有一些事情可以做,使這一進程少艱苦......

  • 打開所有的責難和警告和解決這些問題
  • 關閉所有的語言擴展
  • 定期編譯和測試在Windows ,不只是在最後
  • 獲取程序員誰喜歡的Windows上的項目
  • 限制自己儘可能少的編譯器,你可以
  • 選擇一個良好maintaine d,很好地支持圖形庫
  • 隔離平臺特定的代碼(例如,在子類中)
  • 款待Windows作爲頭等公民

最重要的事情是做這一切從一開始就。可移植性不是你在最後使用的東西。不只是你的代碼,但如果你不警惕,你的整個設計就會變得不可移植。

+4

'關於標準的好處是您有太多可供選擇的選擇.'--) – Voo

-3

與C相比,C++的可移植性非常有限,如果不是完全沒有的話。對於一個你不能禁用異常(你可以),因爲該標準特別說這是未定義的行爲。許多設備甚至不支持異常。因此,C++是零可移植的。再加上看到UB,它顯然是一個禁止零失敗的高性能實時系統,其中的異常是禁忌 - 未定義行爲在零故障環境中沒有位置。那麼這個名字就會變成大多數,如果不是每個編譯器都完全不同的話。爲了實現良好的可移植性和兼容性,extern「C」必須用於導出符號,但這會使任何和所有名稱空間信息完全無效,從而導致重複符號。人們可以選擇不使用名稱空間並使用唯一的符號名稱。另一個C++特性呈現爲void。然後就是語言的複雜性,這導致了各種架構的編譯器的實現困難。由於這些困難,真正的便攜性成爲一個問題。人們可以通過編譯器指令/#ifdefs/macros來解決這個問題。模板?甚至沒有被大多數編譯器支持。

什麼便攜性?你的意思是幾個主流構建目標(如Windows的MSVC和Linux的GCC)之間的半可移植性?即使在那裏,在主流片段中,也存在所有上述問題和限制。它甚至認爲C++是可移植的。

+1

您提出的大部分觀點都與以下問題無關:*「我可以在不同的平臺上編譯兼容的C++代碼嗎?」*對於這個問題的答案有你所描述的問題的**沒有**。你不能(也不會)禁用異常,因爲那樣它就不再是C++了。名稱修改也不是問題。這是編譯器和鏈接器之間的契約,他們會同意任何給定的工具鏈。缺乏模板支持?呃...是的。那是上個千年。 – IInspectable