C語言32位和64位程式設計注意事項

2021-09-19 05:01:40 字數 2286 閱讀 3513

1.ilp32和lp64資料模型

32位環境涉及"ilp32"資料模型,是因為c資料型別為32位的int、long、指標。而64位環境使用不同的資料模型,此時的long和指標已為64位,故稱作"lp64"資料模型。

data type

data length(32bit)

data length(64bit)

signed

char

yunsigned char

nshort

yunsigned short

nint

yunsigned int

nlong 32

64 y

unsigned long 32

64 n

long long

ypoint 32

64 n

size_t 32

64 n

ssize_t 32

64 y

off_t 32

64 y

2.向64位移植**時的所有問題差不多都可以總結出乙個簡單的規律:千萬不要認為int、long、指標的長度一樣。

3.strlen返回size_t(它在lp64中是unsigned long),當賦值給乙個int時,截斷是必然發生的。而通常,截斷只會在str的長度大於2gb時才會發生,這種情況在程式中一般不會出現。

4.那些以十六進製制或二進位制表示的常量,通常都是32位的。例如,無符號32位常量0xffffffff通常用來測試是否為-1:

#define invalid_pointer_value 0xffffffff

然而,在64位系統中,這個值不是-1,而是4294967295;在64位系統中,-1正確的值應為0xffffffffffffffff。要避免這個問題,在宣告常量時,使用const,並且帶上signed或unsigned。

const signed int invalid_pointer_value = 0xffffffff;

這行**將會在32位和64位系統上都執行正常。

5.聯合體問題(union)

當聯合本中混有不同長度的資料型別時,可能會導致問題。下面是乙個常見的開源**包,可在ilp32卻不可在lp64環境下執行。**假定長度為2的unsigned short陣列,占用了與long同樣的空間,可這在lp64平台上卻不正確。

typedef struct size;

} _ucheader_t;

6.符號擴充套件

要避免有符號數與無符號數的算術運算。在把int與long數值作對比時,此時產生的資料提公升在lp64和ilp32中是有差異的。因為是符號位擴充套件,所以這個問題很難被發現,只***兩端的運算元均為signed或均為unsigned,才能從根本上防止此問題的發生。

long k;

int i = -2;

unsigned int j = 1;

k = i + j;

printf("answer: %ld\n", k);

你無法期望答案是-1,然而,當你在lp64環境中編譯此程式時,答案會是4294967295。原因在於表示式(i+j)是乙個 unsigned int表示式,但把它賦值給k時,符號位沒有被擴充套件。要解決這個問題,兩端的運算元只要均為signed或均為unsigned就可。

long k;

int *ptr;

int main(void)

這是乙個有此問題的明顯例子,乙個宣告指向int的指標,卻不經意間指向了long。在ilp32上,這段**列印出2,因為int與long長度一樣。但到了lp64上,因為int與long的長度不一,而導致指標被截斷。不管怎麼說,在小尾位元組序的系統中,**依舊會給出k的正確答案2,但在大尾位元組序(big-endian)系統中,k的值卻是0。

8.移植到64位平台之後的效能降低

當**移植到64位平台之後,也許發現效能實際上降低了。原因與在lp64中的指標長度和資料大小有關,並由此引發的快取命中率降低、資料結構膨脹、資料對齊等問題。 

9.64位體系結構出現的原因在於應用需要更大的定址空間。這些應用可能是高效能的伺服器,資料管理系統,cad或者遊戲。這些應用將從64位位址空間和更多地暫存器中得到大量的效能提公升。需要大量的記憶體的應用可以期待著有更高的效能提公升。

10.開啟和關閉編譯時警告:

-w的意思是關閉編譯時的警告,也就是編譯後不顯示任何warning,因為有時在編譯之後編譯器會顯示一些例如資料轉換之類的警告,這些警告是我們平時可以忽略的。

-wall選項意思是編譯後顯示所有警告。

-w選項類似-wall,會顯示警告,但是只顯示編譯器認為會出現錯誤的警告。

在編譯一些專案的時候可以-w和-wall選項一起使用。

語言程式設計需要注意的64位和32位機器的區別

一 資料型別特別是int相關的型別在不同位數機器的平台下長度不同。c99標準並不規定具體資料型別的長度大小,只規定級別。作下比較 16位平台 char 1個位元組8位 short 2個位元組16位 int 2個位元組16位 long 4個位元組32位 指標 2個位元組 32位平台 char 1個位元...

C語言 32位,64位機器sizeof區別

float,double 採用ieee標準浮點數格式,格式固定float 32bit,double 64bit int一般和cpu暫存器長度有關,不過也和編譯器,彙編器有關 由於c c 標準沒有規定整數型別的固定長度。同一cpu不同作業系統和編譯器,對於int 型別規定的長度是不同的 於是為了區別這...

C語言 32位,64位機器sizeof區別

float,double 採用ieee標準浮點數格式,格式固定float 32bit,double 64bit int一般和cpu暫存器長度有關,不過也和編譯器,彙編器有關 由於c c 標準沒有規定整數型別的固定長度。同一cpu不同作業系統和編譯器,對於int 型別規定的長度是不同的 於是為了區別這...