首页 > 解决方案 > 如何声明比 CPU 机器大的紧凑型?

问题描述

有时,我需要声明一个类型,它的工作方式类似于简单类型,它的大小可能比 cpu 的寄存器大,在某些机器上,在其他机器上则不然。

例如,在 32 位或 64 位机器中的 UUID(128 位)或(128 位)日期时间。

在某些情况下,已经有多平台库,但在另一种情况下没有。

我知道建议坚持使用现有的库,但是,如果没有,我应该怎么做?

例子:

typedef
  uint_16 /* redeclare as */ code16;
  uint_32 /* redeclare as */ code32;

// option 1
struct code64
{
  packed uint_32 A, B;
};

// option 2
struct code64
{
  aligned uint32_t A, B;
};

// option 3
typedef
  packed uint_16 code64[4];

void Example( )
{ 
  code64 A = Foo();
  code64 B = Bar();
  code64 Q = Zaz(A, B);
}

正如标签所示,我希望它在“C”和“C++”中都被编译。

我已经在 stackoverflow 上的其他问题中搜索了这个主题。

标签: c++c

解决方案


结构体的工作方式类似于简单类型,用于传递它、获取其地址sizeof等。要在其中存储一些非结构化数据,请创建一个包含单个数组字段的结构体。

typedef struct {
    uint8_t a[16];
} code128;

根据您要存储的内容,您可能希望在结构中放置更多结构。例如,UUID 被正式定义为具有一定大小的字段,其中一些以平台字节序存储。(但并非所有软件都关心字节顺序,现代软件通常将 UUID 视为一堆字节。)

typedef struct {
    uint32_t time_low;
    uint16_t time_mid;
    uint16_t time_hi_and_version;
    uint8_t clock_seq_hi_and_res;
    uint8_t clock_seq_low;
    uint8_t node[6];

对于 128 位时间,这可能取决于时间的计算方式。通常将时间表示为 64 位秒数和多个分数,例如纳秒或 2^64 秒。例如,现代 Unix 系统有这种类型:

typedef struct timeval {
    uint64_t tv_sec;
    uint64_t tv_usec;
};

您不能对这些结构进行算术运算,但无论如何算术对 UUID 毫无意义,并且时间算术通常不是直接算术,因为具有亚秒精度的时间通常不表示为单个数字。

如果您确实需要算术,某些平台会提供uint128_t,但这不是可移植的(任何 C 或 C++ 实现都必须提供至少 64 位的整数类型,但不必超出此范围)。例如,GCC 和 Clang 都提供双宽度整数类型,因此它们uint128_t在 CPU 具有 64 位寄存器的机器上提供,但最多只能uint64_t在 32 位 CPU 上提供。


推荐阅读