5

我的问题是关于指向奇数大小的内存块。

假设我有一个struct这样的声明:

typedef struct{
   int32 val1  : 29; 
   int32 val2  : 26;
   char  val3;
}MyStruct;

让我们假设在结构中声明特定的位字段是可取的(为什么我们要使用位字段不是问题)。

如果我想声明一个指向这些字段之一的指针,我可能会尝试这样的事情:

MyStruct test;
int32 *myPtr = &(test.val1);

除了这会产生错误“不允许获取位域的地址”。

假设我们想要,有没有办法以这种方式指向这些字段?我知道 C++ 可能会将字段填充到下一个字节(在本例中为 32 位)。

4

3 回答 3

12

在 C++ 中,最小的可寻址值必须具有至少 1 个字节的大小。所以不,你不能用指针获取位域的地址。

C++03 标准 9.6 位域:
第 3 段:

...地址运算符& 不应应用于位域,因此没有指向位域的指针。……

于 2012-06-19T12:02:34.663 回答
6

除了这会产生错误“不允许获取位字段的地址”。

标准明确不允许这样做。参见[class.bit] 9.6/3:

地址运算符 & 不应应用于位域,因此没有指向位域的指针。

一个字节(CHAR_BIT位宽,CHAR_BIT至少为 8)是您可以寻址的最小值。

假设我们想要,有没有办法以这种方式指向这些字段?

不,你可以有一个指向封闭struct类型对象的指针。这是从 C 中直接继承的;请参阅C 常见问题解答 2.26

当您还希望能够将某些位集合作为一个整体进行操作(可能是复制一组标志)时,位域很不方便。

您可能想查看其他替代方案,例如std::bitsetor boost::dynamic_bitset

于 2012-06-19T12:14:54.220 回答
0

没有办法获得指向位域的指针。但是,如果您愿意自己实现一个等效结构,使用移位和掩码,您应该能够在其中定义一个智能指针。就像是:

class BitFieldPointer
{
    unsigned* myData;
    unsigned  myMask;
    unsigned  myShift;

    class DereferenceProxy
    {
        BitFieldPointer const* myOwner;
    public:
        DereferenceProxy(BitFieldPointer const* owner) : myOwner( owner ) {} operator unsigned() const
        {
            return (*myOwner->myData && myOwner->myMask) >> myOwner->myShift;
        }

        void operator=( unsigned new_value ) const
        {
            *myData = (*myOwner->myData && ~myOwner->myMask) |
                    ((new_value << myOwner->myShift) && myOwner->myMask);
        }
    };
public:
    //  ...
    DereferenceProxy operator*() const
    {
        return DereferenceProxy(this);
    }
};

(这只是一个粗略的想法。您可能需要一个指针和一个指向 const 的指针,代理的生命周期与其所有者的生命周期可能是一个问题。)

于 2012-06-19T12:44:04.303 回答