C中的位域内存管理

前端之家收集整理的这篇文章主要介绍了C中的位域内存管理前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
为了理解位字段存储器,我在下面创建了测试程序.
#include <stdio.h>

int main()
{
    int a;
    typedef struct {
        int b7 : 1;
        int b6 : 1;
        int b5 : 1;
        int b4 : 1;
        int b3 : 1;
        int b2 : 1;
        int b1 : 1;
        int b0 : 1;
    } byte;

    byte ab0 = {0,1};
    a = *(int*)&ab0;
    printf("ab0 is %x \n",a);

    byte ab1 = {0,1,0};
    a = *(int*)&ab1;
    printf("ab1 is %x \n",a);

    byte ab2 = {0,0};
    a = *(int*)&ab2;
    printf("ab2 is %x \n",a);

    byte ab3 = {0,0};
    a = *(int*)&ab3;
    printf("ab3 is %x \n",a);

    byte ab4 = {0,0};
    a = *(int*)&ab4;
    printf("ab4 is %x \n",a);

    byte ab5 = {0,0};
    a = *(int*)&ab5;
    printf("ab5 is %x \n",a);

    byte ab6 = {0,0};
    a = *(int*)&ab6;
    printf("ab6 is %x \n",a);

    byte ab7 = {1,0};
    a = *(int*)&ab7;
    printf("ab7 is %x \n",a);

    return 0;
}

编译并运行

gcc -Wall test.c
./a.out 
ab0 is 80 
ab1 is 40 
ab2 is 20 
ab3 is 10 
ab4 is 8 
ab5 is 4 
ab6 is 2 
ab7 is 1

我在线运行代码输出相同
http://codepad.org/ntqyuixp

我无法理解它的输出.

预期产出:
根据我的理解输出应该是

ab0 is 1 
ab1 is 2 
ab2 is 4 
ab3 is 8 
ab4 is 10 
ab5 is 20 
ab6 is 40 
ab7 is 80

>请让我知道我错过了什么.
> endianness是否扮演任何角色?
>如何为我预期的行为编写代码

解决方法

位字段中的位的顺序是实现定义的.实现与您期望的定义有不同的定义 – 几乎所有关于它的定义.

关于位字段的几乎所有内容都是实现定义的.

ISO / IEC 9899:2011§6.7.2.1结构和联合说明符

¶4 The expression that specifies the width of a bit-field shall be an integer constant
expression with a nonnegative value that does not exceed the width of an object of the
type that would be specified were the colon and expression omitted.122) If the value is
zero,the declaration shall have no declarator.

¶5 A bit-field shall have a type that is a qualified or unqualified version of _Bool,signed
int
,unsigned int,or some other implementation-defined type. It is
implementation-defined whether atomic types are permitted.

¶9 A member of a structure or union may have any complete object type other than a
variably modified type.123) In addition,a member may be declared to consist of a
specified number of bits (including a sign bit,if any). Such a member is called a
bit-field;124) its width is preceded by a colon.

¶10 A bit-field is interpreted as having a signed or unsigned integer type consisting of the
specified number of bits.125) If the value 0 or 1 is stored into a nonzero-width bit-field of
type _Bool,the value of the bit-field shall compare equal to the value stored; a _Bool
bit-field has the semantics of a _Bool.

¶11 An implementation may allocate any addressable storage unit large enough to hold a bitfield. If enough space remains,a bit-field that immediately follows another bit-field in a structure shall be packed into adjacent bits of the same unit. If insufficient space remains,whether a bit-field that does not fit is put into the next unit or overlaps adjacent units is implementation-defined. The order of allocation of bit-fields within a unit (high-order to low-order or low-order to high-order) is implementation-defined. The alignment of the addressable storage unit is unspecified.

¶12 A bit-field declaration with no declarator,but only a colon and a width,indicates an
unnamed bit-field.126) As a special case,a bit-field structure member with a width of 0 indicates that no further bit-field is to be packed into the unit in which the prevIoUs bitfield,if any,was placed.

122) While the number of bits in a _Bool object is at least CHAR_BIT,the width (number of sign and value bits) of a _Bool may be just 1 bit.

123) A structure or union cannot contain a member with a variably modified type because member names are not ordinary identifiers as defined in 6.2.3.

124) The unary & (address-of) operator cannot be applied to a bit-field object; thus,there are no pointers to or arrays of bit-field objects.

125) As specified in 6.7.2 above,if the actual type specifier used is int or a typedef-name defined as int,then it is implementation-defined whether the bit-field is signed or unsigned.

126) An unnamed bit-field structure member is useful for padding to conform to externally imposed layouts.

特别注意¶11:

The order of allocation of bit-fields within a unit (high-order to low-order or low-order to high-order) is implementation-defined.

另请注意,“实现定义”意味着实现必须定义它的功能.也就是说,您可以检查文档,文档必须告诉您编译器的作用(如果编译器符合标准).这与“未指定”以及您将遇到的其他一些术语不同 – 编译器编写器几乎肯定不会随意更改位字段从发布到发布的行为.相反,例如,评估函数参数的方式可能会在发布之间发生变化,或者根据编译时选择的优化选项等进行更改.

§6.5.2.2 Function calls

There is a sequence point after the evaluations of the function designator and the actual arguments but before the actual call. Every evaluation in the calling function (including other function calls) that is not otherwise specifically sequenced before or after the execution of the body of the called function is indeterminately sequenced with respect to the execution of the called function.94)

94) In other words,function executions do not ‘‘interleave’’ with each other.

6.7.2 Type specifiers

5 Each of the comma-separated multisets designates the same type,except that for bit-fields,it is implementation-defined whether the specifier int designates the same type as signed int or the same type as unsigned int.

猜你在找的C&C++相关文章