C指针和位设置问题

时间:2011-02-04 16:44:11

标签: c bit-manipulation

作为这个问题的背景,这是我编写的一个测试程序,用于调查我在我工作的消息传递程序中看到的一些奇怪的行为。我们有各种结构使用位标志来保存有关消息的状态,一些标志使用char,一些使用short。我们必须将消息转储到平面文件的实用程序在这些标志值上使用char *来提取设置,因此我故意在flag2上使用不同的指针。

在AIX UNIX 6.1上运行此程序时,为什么输出:

2套
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;
}

3 个答案:

答案 0 :(得分:4)

AIX是一个大端架构,这意味着g指向flag的最重要字节。这意味着对最低有效字节的任何更改对g都是不可见的。

flag2也从未初始化,因此它将包含一些arbirary值。所以事实证明,当它只是开头的那些生活价值时,你会认为有点设置有效。

如果你在像x86这样的小端机器上运行,事情应该按照预期运行。

答案 1 :(得分:0)

我看到了一些可能成为问题的事情。

  1. 您尚未初始化flag2

  2. 你可能想要施放g= (short * ) &flag2,因为如果你施展 char你不一定会 获得最少的参考 重要的8位。

答案 2 :(得分:0)

来自维基百科的pointers

  

2005年C标准草案   需要投射指针   从一种类型派生到一种类型   另一种类型应该保持   两种类型的对齐正确性   (6.3.2.3指针,第7段):[3]

char *external_buffer = "abcdef";
int *internal_data;

internal_data = (int *)external_buffer;  // UNDEFINED BEHAVIOUR if "the resulting pointer
                                         // is not correctly aligned"

底线: 使用正确的指针类型

行为可能会按预期工作,但不能保证。

C ++ 03标准$ 5.3.3 / 1说,

sizeof(char), sizeof(signed char) and sizeof(unsigned char) are 1; the
     

sizeof应用于任何其他的结果   基本类型(3.9.1)是   实现定义。 [注意:在   特别是,sizeof(bool)和   sizeof(wchar_t)是   实施-defined.69)

看看这个:C++ Size of primitives