11.1. 標(biāo)準(zhǔn) C 類(lèi)型的使用

2018-02-24 15:50 更新

11.1.?標(biāo)準(zhǔn) C 類(lèi)型的使用

盡管大部分程序員習(xí)慣自由使用標(biāo)準(zhǔn)類(lèi)型, 如 int 和 long, 編寫(xiě)設(shè)備驅(qū)動(dòng)需要一些小心來(lái)避免類(lèi)型沖突和模糊的 bug.

這個(gè)問(wèn)題是你不能使用標(biāo)準(zhǔn)類(lèi)型, 當(dāng)你需要"一個(gè) 2-字節(jié) 填充者"或者"一個(gè)東西來(lái)代表一個(gè)4-字節(jié) 字串", 因?yàn)檎5?C 數(shù)據(jù)類(lèi)型在所有體系上不是相同大小. 為展示各種 C 類(lèi)型的數(shù)據(jù)大小, datasize 程序已包含在例子文件 misc-progs 目錄中, 由 O' Reilly's FTP 站點(diǎn)提供. 這是一個(gè)程序的樣例運(yùn)行, 在一個(gè) i386 系統(tǒng)上(顯示的最后 4 個(gè)類(lèi)型在下一章介紹):


morgana% misc-progs/datasize
arch Size: char short int long ptr long-long u8 u16 u32 u64
i686       1    2     4   4    4   8         1  2   4   8

這個(gè)程序可以用來(lái)顯示長(zhǎng)整型和指針在 64-位 平臺(tái)上的不同大小, 如同在不同 Linux 計(jì)算機(jī)上運(yùn)行程序所演示的:


arch  Size:  char  short  int  long  ptr long-long  u8 u16 u32 u64 
i386         1     2      4    4     4   8          1  2   4   8  
alpha        1     2      4    8     8   8          1  2   4   8  
armv4l       1     2      4    4     4   8          1  2   4   8  
ia64         1     2      4    8     8   8          1  2   4   8  
m68k         1     2      4    4     4   8          1  2   4   8  
mips         1     2      4    4     4   8          1  2   4   8  
ppc          1     2      4    4     4   8          1  2   4   8  
sparc        1     2      4    4     4   8          1  2   4   8  
sparc64      1     2      4    4     4   8          1  2   4   8  
x86_64       1     2      4    8     8   8          1  2   4   8  

注意有趣的是 SPARC 64 體系在一個(gè) 32-位 用戶(hù)空間運(yùn)行, 因此那里指針是 32 位寬, 盡管它們?cè)趦?nèi)核空間是 64 位寬. 這可用加載 kdatasize 模塊(在例子文件的 misc-modules 目錄里)來(lái)驗(yàn)證. 這個(gè)模塊在加載時(shí)使用 printk 來(lái)報(bào)告大小信息, 并且返回一個(gè)錯(cuò)誤( 因此沒(méi)有必要卸載它 ):


kernel: arch Size: char short int long ptr long-long u8 u16 u32 u64
kernel: sparc64    1    2     4   8    8   8         1  2   4   8

盡管在混合不同數(shù)據(jù)類(lèi)型時(shí)你必須小心, 有時(shí)有很好的理由這樣做. 一種情況是因?yàn)閮?nèi)存存取, 與內(nèi)核相關(guān)時(shí)是特殊的. 概念上, 盡管地址是指針, 內(nèi)存管理常常使用一個(gè)無(wú)符號(hào)的整數(shù)類(lèi)型更好地完成; 內(nèi)核對(duì)待物理內(nèi)存如同一個(gè)大數(shù)組, 并且內(nèi)存地址只是一個(gè)數(shù)組索引. 進(jìn)一步地, 一個(gè)指針容易解引用; 當(dāng)直接處理內(nèi)存存取時(shí), 你幾乎從不想以這種方式解引用. 使用一個(gè)整數(shù)類(lèi)型避免了這種解引用, 因此避免了 bug. 因此, 內(nèi)核中通常的內(nèi)存地址常常是 unsigned long, 利用了指針和長(zhǎng)整型一直是相同大小的這個(gè)事實(shí), 至少在 Linux 目前支持的所有平臺(tái)上.

因?yàn)槠渌档脑? C99 標(biāo)準(zhǔn)定義了 intptr_t 和 uintptr_t 類(lèi)型給一個(gè)可以持有一個(gè)指針值的整型變量. 但是, 這些類(lèi)型幾乎沒(méi)在 2.6 內(nèi)核中使用.

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)