从成员中查找结构基地址的标准方法 [英] Standard way to find base address of struct from a member

查看:105
本文介绍了从成员中查找结构基地址的标准方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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
}

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

I have a Data instance allocated on the heap, and a pointer to its std::string b; member. How do I get the base address of the Data instance the string is a member of, taking into account offsets and padding, in a standard way?

我尝试从std::string*指针中减去sizeof(int)std::offsetof(Data, std::string),但是我无法使它起作用.

I've tried subtracting sizeof(int) and std::offsetof(Data, std::string) from the std::string* pointer, but I couldn't get it to work.

推荐答案

使用<cstddef>中的offsetof,但请注意,它仅在标准布局类型上定义(

Use offsetof from <cstddef>, but beware it is only defined on standard-layout types (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)
    );
}

offsetof在C ++ 11 18.2/4中有详细说明:

offsetof is detailed in C++11 18.2/4:

offsetof( type member-designator )在此国际标准中接受一组受限制的类型参数.如果 type 不是标准布局类(第9条),则结果是不确定的. 195 表达式offsetof( type member-designator )从不依赖于类型(14.6.2.2),并且仅当 type 是依赖于值时,才依赖于值(14.6.2.3).将offsetof宏应用于静态数据成员或函数成员的字段的结果是不确定的. offsetof宏调用的任何操作都不会抛出异常,并且noexcept(offsetof(type, member-designator))应该是true.

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:

and C99 (N1256) 7.17/3:

宏是

NULL

扩展为实现定义的空指针常量;和

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

offsetof(type, member-designator)

扩展为一个整数常量表达式,其类型为size_t,其值是从...的开头到结构成员(由 member-designator 指定)的偏移量(以字节为单位).其结构(由 type 指定).类型和成员指示符应为给定的

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

static type t;

然后,表达式&(t. member-designator )得出一个地址常数. (如果指定的成员是位字段,则行为是不确定的.)

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标准的情况更具限制性.

The "restricted set of type arguments in this International Standard" in the C++ standard is there to draw your attention to the fact that offsetof is more restrictive than is the case for the C standard.

这篇关于从成员中查找结构基地址的标准方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆