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

时间:2009-10-09 23:26:12

标签: c portability standards iso

是否有一种可靠的方法来为ISO标准C中固定的8,16,32和64位长度的整数类型声明typedef?

当我说ISO标准C时,我的意思是:

  • ISO C89 / C90,而不是C99。
  • ISO标准中未定义任何标题。
  • ISO标准中未定义预处理器符号。
  • ISO标准中未指定类型大小的假设。
  • 没有专有供应商符号。

我在StackOverflow中看到了与此类似的其他问题,但还没有任何答案违反上述约束之一。如果不诉诸平台符号,我不确定是否可能。

5 个答案:

答案 0 :(得分:8)

你可以。

头文件limits.h应该是C90的一部分。然后我将测试SHRT_MAXINT_MAXLONG_MAXLLONG_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

答案 1 :(得分:6)

严格来说,ISO 9899:1999取代了ISO 9899:1990,因此是目前唯一的ISO标准C语言规范。

由于整数类型的精确宽度typedef名称仅在1999版本的标准中引入,因此仅使用1990版本的标准无法实现所需。

答案 2 :(得分:3)

没有。有一种可靠的方法来声明大小最多为32位的单个整数变量,但是,如果您愿意接受一些限制。只需使用long位域(后者保证至少为32位宽,并且如果省略了位域声明符,则允许在位域中使用最多可以容纳变量的位)。所以:

struct {
   unsigned long foo : 32; 
} bar;

显然,你得到了所有的限制,例如无法指向这些变量。唯一真正购买的东西是保证在上溢/下溢的指定边界上的环绕,甚至只有无符号类型,因为溢出未定义为签名。

除此之外,在纯C90中没有可移植的方法。除此之外,符合要求的C90实现甚至不需要8位整数 - 例如,拥有sizeof(char) == sizeof(short) == sizeof(int) == 1CHAR_BIT == 16的平台(即它具有16-)是完全合法的。位机字,并不能解决单个字节)。我听说这些平台确实存在于某些DSP的实践中。

答案 3 :(得分:0)

不,你做不到。

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

答案 4 :(得分:0)

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