基礎:機器模型

可攜性與平台/目標

如果你用公制單位寫一份食譜,而某個使用杯與盎司的國家的人想照著做,這份食譜就得換算。軟體面對同樣的問題:在你筆電上跑得好好的程式碼,到別處可能跑不動,因為「別處」在某些程式碼默默倚賴的地方並不相同。可攜性,指的是一個程式能多容易地被弄到不同平台上跑;而平台(或目標)就是某程式所針對建構的那組特定組合:CPU、作業系統與工具鏈。

一個平台綑綁了好幾樣東西:CPU 架構(它懂哪種機器碼——比如 x86-64 或 ARM)、作業系統(Linux、macOS、Windows——存在哪些系統呼叫與慣例),以及往往還包括可用的函式庫與編譯器。一個程式若能幾乎不改、就被搬到另一平台,就是可攜的。對 C 這類編譯式語言,可攜性通常指同一份原始碼能在每個目標上重新編譯,而非同一個可執行檔到處都能跑——因為可執行檔是針對某一平台的機器碼。「目標」不過就是你正在為之建構的那個平台,它可以跟你用來建構的那台不同(這就是交叉編譯)。

為何重要:可攜性在系統程式設計中是一股恆常的張力,因為那些賦予你力量的極低階細節——確切的整數大小、位元組序、可用的系統呼叫、記憶體排佈——正是各平台之間會不同的東西。C 作為語言以可攜聞名,卻滿是利刃(int 不總是同樣大小;某些行為是「實作定義」的),在你搬動程式碼時咬人。寫可攜的程式碼,意味著有意識地不去倚賴你那一台機器的偶然性;而標準的存在,大半正是為了讓這件事成為可能。

同一份 hello.c 在 Linux x86-64 伺服器與 Apple 晶片的 Mac 上都能編譯並執行——那份原始碼是可攜的。但在 Linux 機器上建出的可執行檔 hello,無法在 Mac 上跑;每個平台都需要自己編譯一次。假設 int 剛好是 4 個位元組的程式碼,可攜性低於使用 int32_t 這種固定寬度型別的程式碼。

可攜的原始碼,平台專屬的可執行檔——每個目標各自重新編譯。

可攜不是「到處跑得一模一樣且毫不費力」,而是「能以合理的力氣搬動」。而且原始碼可攜不等於可執行檔可攜:在 C 裡,逐個目標重新編譯才是常態,倚賴機器專屬的細節(int 寬度、位元組序)會悄悄把它弄壞。

又稱
portabilityplatformtargetcross-platform可移植性目標平台