歷史上,C 語言的實作方式差異很大,許多系統也缺乏 ANSI/ISO C89 的完整實作。然而,現今所有實用的系統都配備了 C89 編譯器,而 GNU C 幾乎支援了所有的 C99 以及部分的 C11 標準。同樣地,大多數系統實作了 POSIX.1-2001 的函式庫和工具,許多系統也實作了 POSIX.1-2008。
因此,現在幾乎沒有理由再去支援舊的 C 語言或非 POSIX 系統,您應該可以善用標準 C 和 POSIX 來編寫更清晰、更易於移植或更快速的程式碼。您應該盡可能使用標準介面;但是,如果 GNU 擴充功能能讓您的程式更易於維護、更強大或更好,請不要猶豫使用它們。無論如何,不要自行宣告系統函數;那樣做很容易造成衝突。
儘管有這些標準,幾乎每個函式庫函數在某些系統上都存在某種可移植性問題。以下是一些範例:
open
名稱結尾帶有 /
的在許多平台上會被錯誤處理。
printf
long double
可能未實作;浮點數值 Infinity 和 NaN 經常被錯誤處理;高精度的輸出可能不正確。
readlink
可能會回傳 int
而不是 ssize_t
。
scanf
在 Windows 上,失敗時不會設定 errno
。
Gnulib 在這方面提供了很大的幫助。Gnulib 在許多缺乏標準介面的系統上提供了標準介面的實作,包括增強型 GNU 介面的可移植實作,從而使其使用具有可移植性,以及 POSIX-1.2008 介面的實作,其中一些介面甚至在最新的 GNU 系統中也缺失。
Gnulib 也提供了許多有用的非標準介面;例如,標準資料結構(雜湊表、二元樹)的 C 語言實作、用於記憶體配置函數(xmalloc
、xrealloc
)的錯誤檢查型別安全包裝函式,以及錯誤訊息的輸出。
Gnulib 與 GNU Autoconf 和 Automake 整合,以減輕程式設計師編寫可移植程式碼的大部分負擔:Gnulib 使您的 configure 腳本自動確定缺少哪些功能,並使用 Gnulib 程式碼來提供缺少的組件。
Gnulib 和 Autoconf 手冊中有關於可移植性的廣泛章節:《Gnulib》簡介 以及 《Autoconf》中的可移植 C 和 C++。請查閱它們以獲得更多詳細資訊。