C指针和位设置问题
作为这个问题的背景,这是我写的一个测试程序,用来调查我们在我工作的一个消息传递程序中看到的一些奇怪的行为。我们有各种各样的结构,使用位标志来保存消息的状态,一些标志使用char,一些使用shorts。我们必须将消息转储到平面文件的一个实用程序是在这些标志值上使用char*来提取设置,因此我故意在flag2上使用不同的指针 当此程序在AIX UNIX 6.1上运行时,为什么输出为: 2套C指针和位设置问题,c,bit-manipulation,C,Bit Manipulation,作为这个问题的背景,这是我写的一个测试程序,用来调查我们在我工作的一个消息传递程序中看到的一些奇怪的行为。我们有各种各样的结构,使用位标志来保存消息的状态,一些标志使用char,一些使用shorts。我们必须将消息转储到平面文件的一个实用程序是在这些标志值上使用char*来提取设置,因此我故意在flag2上使用不同的指针 当此程序在AIX UNIX 6.1上运行时,为什么输出为: 2套 4套 8套 16套 64套 值1和32发生了什么变化 #include <stdio.h> #d
4套
8套
16套
64套 值1和32发生了什么变化
#include <stdio.h>
#define SET(x,y) y |= (x)
#define UNSET(x,y) y &= (~x)
int main ( int argc, char *argv[] )
{
unsigned char *g;
unsigned short *h;
unsigned long *i;
char flag1;
short flag2;
long flag3;
g = (char*) &flag2;
SET(1, flag2);
if ( 1 & *g )
printf("1 set\n");
UNSET(1, flag2);
SET(2, flag2);
if ( 2 & *g )
printf("2 set\n");
UNSET(2, flag2);
SET(4, flag2);
if ( 4 & *g )
printf("4 set\n");
UNSET(4, flag2);
SET(8, flag2);
if ( 8 & *g )
printf("8 set\n");
UNSET(8, flag2);
SET(16, flag2);
if ( 16 & *g )
printf("16 set\n");
UNSET(16, flag2);
SET(32, flag2);
if ( 32 & *g )
printf("32 set\n");
UNSET(32, flag2);
SET(64, flag2);
if ( 64 & *g )
printf("64 set\n");
UNSET(64, flag2);
return 0;
}
#包括
#定义集合(x,y)y |=(x)
#定义未设置(x,y)y&=(~x)
int main(int argc,char*argv[])
{
无符号字符*g;
无符号短*h;
无符号长*i;
字符标志1;
短旗2;
长旗3;
g=(字符*)&flag2;
设置(1,2);
if(1&*g)
printf(“1套\n”);
未设置(1,2);
集合(2,flag2);
if(2&*g)
printf(“2套\n”);
未设置(2,flag2);
组(4,2);
if(4&*g)
printf(“4套\n”);
未设置(4,2);
组(8,2);
if(8&*g)
printf(“8套\n”);
未设置(8,2);
集合(16,flag2);
if(16&*g)
printf(“16套”);
未设置(16,2);
集合(32,flag2);
if(32&*g)
printf(“32集\n”);
未设置(32,2);
集合(64,flag2);
if(64&*g)
printf(“64集\n”);
未完成(64,2);
返回0;
}
我发现有两件事可能是问题所在
flag2
g=(short*
)&flag2
,因为如果您强制转换为
你不一定是
获取对最小值的引用
有效8位AIX是一个big-endian体系结构,这意味着
g
指向标志
的最高有效字节。这意味着对最低有效字节的任何更改对g
不可见
flag2
也从未初始化,因此它将包含一些任意值。结果证明,当一开始只是任意值时,你认为某个位设置起作用了
如果您在x86这样的小型endian机器上运行,事情应该按照预期运行。来自维基百科:
2005年的C标准草案
需要强制转换指针
从一种类型派生到以下类型之一
另一种类型应保持
两种类型的对齐正确性
(3.3.2.3指针,Par 7):(3)< /P>
底线:使用右指针类型
该行为可能按预期工作,但不能保证
C++03标准$5.3.3/1表示
sizeof的结果适用于任何其他
基本类型(3.9.1)为
实现定义。[注:在
特别是sizeof(bool)和
sizeof(wchar\t)是
实施(第69段)
看看这个:您可能希望显式地将
flag2
初始化为0。flag2很短,但您要将指向它的指针转换为char*,请改用short*(那么g也应该是short类型)。我在HP UX上运行该程序,它根本不打印任何内容,但当我在Fedora上运行同一程序时,它可以工作。为什么在短字符上使用字符指针?但他在检查其状态之前设置了每一位他可能在检查不同的内存位置,*g可能指的是最高有效的8位,而不是最低有效的he应为@BlackBear:SET(1,flag2)
大概是在一个不同的字符中设置了一个位,而不是1&*g
测试的字符。@bobbogo,@eric:是的,我错过了这个细节。:)是的,这就是我所期望的,这就是为什么忽略初始化不会像应该的那样隐藏。不仅因为它是大端,而且因为short和char恰好大小不同。
char *external_buffer = "abcdef";
int *internal_data;
internal_data = (int *)external_buffer; // UNDEFINED BEHAVIOUR if "the resulting pointer
// is not correctly aligned"
sizeof(char), sizeof(signed char) and sizeof(unsigned char) are 1; the