簡體   English   中英

在標准C中聲明固定大小的整數typedef

[英]Declaring fixed-size integer typedef in Standard C

是否有一種可靠的方法來為ISO標准C中的固定8,16,32和64位長度的整數類型聲明typedef?

當我說ISO標准C時,我的意思是:

  • ISO C89 / C90,而不是C99。
  • 沒有在ISO標准中定義的標頭。
  • 沒有在ISO標准中定義的預處理器符號。
  • ISO標准中未指定類型大小的假設。
  • 沒有專有供應商符號。

我在StackOverflow中看到了與此類似的其他問題,但沒有答案尚未違反上述約束之一。 如果不訴諸平台符號,我不確定是否可行。

是的,你可以。

頭文件limits.h應該是C90的一部分。 然后,我將測試SHRT_MAXINT_MAXLONG_MAXLLONG_MAX預處理器指令值,並LLONG_MAX設置typedef。

例:

#include <limits.h>

#if SHRT_MAX == 2147483647
typedef unsigned short int uint32_t;
#elif INT_MAX == 2147483647
typedef unsigned int uint32_t;
#elif LONG_MAX == 2147483647
typedef unsigned long uint32_t ;
#elif LLONG_MAX == 2147483647
typedef unsigned long long uint32_t;
#else
#error "Cannot find 32bit integer."
#endif

嚴格來說,ISO 9899:1999取代了ISO 9899:1990,因此是目前唯一的ISO標准C語言規范。

由於整數類型的精確寬度typedef名稱僅在1999版本的標准中引入,因此僅使用1990版本的標准是不可能的。

空無一人。 有一種可靠的方法來聲明大小最多為32位的單個整數變量,但是,如果您願意接受一些限制。 只需使用long位域(后者保證至少為32位寬,並且如果省略了位域聲明符,則允許在位域中使用盡可能多的位,以適應變量)。 所以:

struct {
   unsigned long foo : 32; 
} bar;

顯然,您會獲得隨之而來的所有限制,例如無法指向此類變量。 唯一真正為你買的東西是保證在上溢/下溢的指定邊界上環繞,甚至只有無符號類型,因為溢出未定義為signed。

除此之外,在純C90中沒有可移植的方法。 除此之外,符合要求的C90實現甚至不需要8位整數 - 例如,擁有一個平台,其中sizeof(char) == sizeof(short) == sizeof(int) == 1CHAR_BIT == 16 (即它有一個16位機器字,並且不能尋址單個字節)。 我聽說這些平台實際上確實以某些DSP的形式存在。

使用現代編譯器時這種方法的危險在於,編譯器假設一個整數類型的指針不會用於訪問另一個整數類型的指針, 即使兩種類型具有相同的大小和表示 ,也已成為時尚。 如果兩種類型具有相同的大小和表示,並且同一程序的兩個部分各自選擇其中一種,則將鏈接時優化應用於共享指向此類數據的指針的程序可能導致不正確的行為。 對於許多系統上的某些實現,將存在至少一個整數大小,對於該整數,將不可能聲明可以安全地用於訪問該大小的所有整數值的指針; 例如,在longlong long都是64位的系統上,將無法聲明一個可以可靠地用於交換訪問任何類型數據的指針。

不,你做不到。

現在,如果你想計算一個像Gnu configure這樣的多階段配置過程作為解決方案,你可以這樣做並堅持使用C89。 當然也有,你可以使用 C89多種類型,而幾乎今天這周圍的每一個執行DTRT,所以你得到你想要的大小,並用純符合的C89堅持。 但是,當您想要的位寬時,通常不會由標准指定。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM