2

即,如果我们将一个名为 arr 的 C 或 C++ 无符号字符数组转换为 (unsigned short*)arr 然后分配给它,结果是否与机器字节序无关?

旁注 - 我看到了关于 IBM 和其他地方关于 SO 的讨论,例如:

unsigned char endian[2] = {1, 0};
short x;
x = *(short *) endian;

...说明 x 的值将取决于字节序的布局,因此取决于机器的字节序。这意味着取消引用数组是依赖于字节序的,但是分配给它呢?

*(short*) endian = 1;

无论字节顺序如何,是否所有未来的短期取消引用都保证返回 1?


阅读回复后,我想发布一些背景信息:

在这个结构中

struct pix { 
    unsigned char r; 
    unsigned char g;
    unsigned char b; 
    unsigned char a; 
    unsigned char y[2]; 
 }; 

用 unsigned short y 替换 unsigned char y[2] 没有个体差异,但是如果我将这些结构组成一个数组并将其放入另一个结构中,那么我注意到容器结构的大小往往更高“无符号短”版本,因此,由于我打算制作一个大型数组,因此我选择了 unsigned char[2] 以节省空间开销。我不知道为什么,但我想在内存中对齐 uchar[2] 更容易。

因为我需要用那个变量 y 做大量的数学运算,这意味着它是一个短长度的数值,我发现自己为了避免单独访问 uchar 字节而进行了很多转换......有点快避免丑陋的特定于字节的数学的方法,但后来我想到了字节顺序以及如果我只是将所有内容都转换为,我的数学是否仍然正确

*(unsigned short*)this->operator()(x0, y0).y = (ySum >> 2) & 0xFFFF;

...这是一个程序中的一行,它平均 2-D 数组中的 4 个相邻邻居,但关键是我有一堆需要对 uchar[2] 字段进行操作的操作作为单个短,我试图找到最轻的(即,每次我需要访问或分配时都没有基于字节序的 if-else 语句),与短字节无关的字节序无关方式。

4

3 回答 3

3

由于严格的指针别名,它是未定义的行为,所以它可能是任何东西。如果你对联合做同样的事情,但答案是否定的,结果取决于机器字节序。

于 2012-05-10T07:24:26.697 回答
3

的每个可能值short都有一个所谓的“对象表示”[*],它是一个字节值序列。当一个类型的对象short保存该值时,该对象的字节保存该值序列。

您可以将字节顺序视为对象表示依赖于实现的方式之一:具有最低地址的字节是保存值的最高有效位还是最低有效位?

希望这能回答你的问题。如果您已经安全地将有效的对象表示形式1作为 short 写入某个内存,那么当您从同一内存中读回它时,您将再次获得相同的值,而不管该1实现中的对象表示实际上是什么。尤其是不管字节顺序。但正如其他人所说,你必须避免未定义的行为。

[*] 或者,在奇异的架构上,相同的值可能有不止一个对象表示。

于 2012-05-10T08:45:14.647 回答
1

是的,所有未来的取消引用也将返回1:就像1在 type 范围内一样short,它最终会在内存中未经修改,并且一旦存在就不会在你背后改变。

unsigned char[2]但是,代码本身违反了有效类型:将a 作为 a访问是非法的,并且如果您的架构不支持未对齐访问并且您特别不走运short,则可能会引发 a 。SIGBUS

但是,任何对象的字符访问始终是合法的,并且代码的可移植版本如下所示:

short value = 1;
unsigned char *bytes = (unsigned char *)&value;

当然,如何value存储在内存中仍然是实现定义的,即如果不进一步了解架构,您将无法知道以下将打印什么:

assert(sizeof value == 2); // check for size 2 shorts
printf("%i %i\n", bytes[0], bytes[1]);
于 2012-05-10T08:37:55.357 回答