在标准C中声明固定大小的整数typedef

是否有一种可靠的方法来为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  #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的forms存在。

不,你做不到。

现在,如果你想计算一个像Gnu configure这样的多阶段配置过程作为解决方案,你可以这样做并坚持使用C89。 当然,你可以在C89中使用各种类型的DTRT,这几乎是今天所有的实现,所以你可以获得你想要的尺寸并坚持使用纯粹的C89。 但是,您想要的位宽通常不会由标准指定。

使用现代编译器时这种方法的危险在于,编译器假设一个整数类型的指针不会用于访问另一个整数类型的指针, 即使两种类型具有相同的大小和表示 ,也已成为时尚。 如果两种类型具有相同的大小和表示,并且同一程序的两个部分各自选择其中一种,则将链接时优化应用于共享指向此类数据的指针的程序可能导致不正确的行为。 对于许多系统上的一些实现,将存在至少一个整数大小,对于该整数,将不可能声明可以安全地用于访问该大小的所有整数值的指针; 例如,在longlong long都是64位的系统上,将无法声明一个可以可靠地用于交换访问任一类型数据的指针。