其他分享
首页 > 其他分享> > c-从成员中查找结构基址的标准方法

c-从成员中查找结构基址的标准方法

作者:互联网

struct Data {
    int a;
    std::string b;
    float c;
};

std::string* allocateDataAndGetString() {
    Data* dataPtr(someAllocator.allocate<Data>());
    return &dataPtr.b;
}

Data* getBaseDataPtrFromString(std::string* mStringMember) {
    // ???
}

int main() {
    std::string* stringPtr(allocateDataAndGetString());
    Data* dataPtr(getBaseDataPtrFromString
}

我在堆上分配了一个数据实例,并有一个指向其std :: string b的指针;会员.如何以标准方式,考虑到偏移量和填充,获取字符串所属的Data实例的基址?

我试过从std :: string *指针中减去sizeof(int)和std :: offsetof(Data,std :: string),但我无法使其正常工作.

解决方法:

使用自< cstddef>的offsetof,但请注意,它仅在标准布局类型(Live at Coliru)上定义:

Data* getBaseDataPtrFromString(std::string* mStringMember) {
    static_assert(std::is_standard_layout<Data>::value,
                  "offsetof() only works on standard-layout types.");
    return reinterpret_cast<Data*>(
      reinterpret_cast<char*>(mStringMember) - offsetof(Data, b)
    );
}

C 11 18.2 / 4中详细介绍了offsetof:

The macro offsetof(type, member-designator) accepts a restricted set of type arguments in this International Standard. If type is not a standard-layout class (Clause 9), the results are undefined.195 The expression offsetof(type, member-designator) is never type-dependent (14.6.2.2) and it is value-dependent (14.6.2.3) if and only if type is dependent. The result of applying the offsetof macro to a field that is a static data member or a function member is undefined. No operation invoked by the offsetof macro shall throw an exception and noexcept(offsetof(type, member-designator)) shall be true.

和C99(N1256)7.17 / 3:

The macros are

06001

which expands to an implementation-defined null pointer constant; and

06002

which expands to an integer constant expression that has type size_t, the value of which is the offset in bytes, to the structure member (designated by member-designator), from the beginning of its structure (designated by type). The type and member designator shall be such that given

06003

then the expression &(t.member-designator) evaluates to an address constant. (If the specified member is a bit-field, the behavior is undefined.)

C标准中的“此国际标准中的类型参数的受限集合”可引起您的注意,即offsetof比C标准的情况更具限制性.

标签:c,c11,struct,memory-address,offsetof
来源: https://codeday.me/bug/20191011/1895188.html