C11 标准保证将一种数组类型转换为另一种数组类型

C11 standard guarantees for casting one array type to another

所以我有一个应用程序,我在其中使用了很多字符、短整型、整型和长整型数组,所有这些都是无符号的。我的想法不是为每个分配 space 并取消分配,而是拥有一个静态的 unsigned long long 数组。然后我会根据需要将其转换为适当类型的数组。有没有办法证明这符合标准?

我静态断言 char、short、int 和 long long 的大小分别为 1、2、4 和 8,并且它们的对齐要求不超过它们的大小。我想知道我是否可以在没有进一步的静态断言的情况下证明我的方法的有效性。

编辑:我想我要补充一点,标准将对象表示定义为一个对象的副本,作为一个无符号字符数组。似乎这证明使用 unsigned long long 数组作为那个数组或 unsigned char 数组是合理的,尽管我不能绝对排除与在对象本身的上下文中而不是在副本中使用对象表示相关的问题(这是 6.2. 6.1.4 讨论对象表示)。然而,这就是我所能找到的所有内容,它对两个中间整数大小没有任何帮助。

首先,您不是在谈论转换 数组。你说的是铸造 pointers.

该标准不保证您所做的是安全的。例如,您可以将 unsigned long long 的数组视为 unsigned char 的数组,但不能保证您可以将其视为 unsigned int.

的数组

考虑 CHAR_BIT==8sizeof (unsigned int) == 4sizeof (unsigned long long) == 8 的假设实现。假设 unsigned int 需要严格的 4 字节对齐。但是底层机器没有直接支持64位数量,所以对unsigned long long的所有操作都是在软件中完成的。因此,比方说,unsigned long long 所需的对齐是 2 个字节。

所以 unsigned long long 的数组可能从不是 4 字节的倍数的地址开始,因此您不能安全地将它视为 unsigned int 的数组。

我不认为这是一个似是而非的实施。即使在软件中实现了 64 位整数,它们至少具有 32 位对齐也可能有意义。但是我所描述的没有任何内容违反标准;假设的实现可能符合要求。

如果您使用的是 C11 编译器(如问题中的标签所示),您可以静态断言

_Alignof (unsigned long long) > _Alignof (unsigned int)

等等。

或者您可以在启动期间使用 malloc 来分配您的数组,确保它针对任何类型正确对齐。

从评论中借鉴一个想法,你可以定义一个数组类型的联合,比如:

#define BYTE_COUNT some_big_number
union arrays {
    unsigned char      ca[BYTE_COUNT];
    unsigned short     sa[BYTE_COUNT  / sizeof (unsigned short)];
    unsigned int       ia[BYTE_COUNT  / sizeof (unsigned int)];
    unsigned long      la[BYTE_COUNT  / sizeof (unsigned long)];
    unsigned long long lla[BYTE_COUNT / sizeof (unsigned long long)];
};

或者您可以根据要在其中存储的数据类型定义数组。