我希望使我的代码更具可移植性,并且我专注于确保我符合C89标准(在这种情况下)。我遇到的问题之一是可能存在填充整数。从GMP手册中摘取的这个极端例子可以说明:
然而,在Cray向量系统上,可以注意到short和int始终存储在8字节中(并且使用
sizeof
指示),但只使用32或46位。通过传递例如8*sizeof(int)-INT_BIT
,可以利用nails功能来解决这个问题。我也在其他地方读到过这种填充方式。昨晚我实际上在 Stack Overflow 上读到了一篇帖子(请原谅,我没有链接,我将从记忆中引用类似的内容),如果你有一个具有60个可用位的双精度数,那么其他4个位可以用于填充,并且这些填充位可以用于某些内部目的,因此不能被修改。
假设我的代码在一个无符号整数大小为4个字节的平台上编译,每个字节占8位,但是最高的2位是填充位。那么在这种情况下,
UINT_MAX
是否为0x3FFFFFFF(1073741823)?#include <stdio.h>
#include <stdlib.h>
/* padding bits represented by underscores */
int main( int argc, char **argv )
{
unsigned int a = 0x2AAAAAAA; /* __101010101010101010101010101010 */
unsigned int b = 0x15555555; /* __010101010101010101010101010101 */
unsigned int c = a ^ b; /* ?? __111111111111111111111111111111 */
unsigned int d = c << 5; /* ?? __111111111111111111111111100000 */
unsigned int e = d >> 5; /* ?? __000001111111111111111111111111 */
printf( "a: %X\nb: %X\nc: %X\nd: %X\ne: %X\n", a, b, c, d, e );
return 0;
}
两个整数进行异或运算时,使用填充位是否安全?
无论填充位是什么,我都会进行异或运算吗?
我在C89中找不到这种行为的说明。
此外,变量c是否保证为0x3FFFFFFF?例如,如果a或b的两个填充位都打开了,那么c是否为0xFFFFFFFF?
对于变量d和e也是同样的问题。通过移位操作,我是否在操作填充位? 假设有32位,其中最高的2位用于填充,我期望看到下面的结果,但我想知道是否有类似的保证:
a: 2AAAAAAA
b: 15555555
c: 3FFFFFFF
d: 3FFFFFE0
e: 01FFFFFF
也就是说,填充位始终是最高有效位吗?还是它们可以是最低有效位?
编辑于2010年12月19日下午5点(美国东部时间):Christoph已经回答了我的问题。谢谢!
我之前也问过(上面)填充位是否总是最高有效位。这在C99标准的理由中有提到,答案是否定的。为了保险起见,我假设C89也是一样的。以下是C99理由中对于§6.2.6.2(整数类型的表示)的具体说明:
脚注44和45提到奇偶校验位可能是填充位。委员会不知道是否有任何具有用户可访问奇偶校验位的机器。因此,委员会不知道是否有任何将奇偶校验位视为填充位的机器。
编辑于2010年12月28日下午3点(美国东部时间):我在几个月前的comp.lang.c上找到了一个有趣的讨论。
迪特马尔提出了一个我觉得很有意思的观点:
值得注意的是,填充位并不是陷阱表示存在的必要条件;不代表对象类型值的组合也可以。
-0
,它可能会成为陷阱表示,并且按位补码运算符可能会导致这样的表示。我假设一个例子是~(int)0
,其中有符号整数表示是一的补码,并且根据实现可能会导致陷阱表示。 - Anonymous Question Guy