3

我放了标签language lawyer,虽然我觉得这是在标准边界的错误一侧。我还没有看到关于这一点的对话,但我在工作中,所以我想对此有一些确定性。

问题是访问(可能)虚拟基类的私有字段。假设我计算了一个类的私有字段的偏移量,然后在类外部使用这个偏移量来访问(读/写)这个位置的成员变量。

我看到有一个GCC和clang的扩展offsetof(这个是在C++17中条件定义的,是什么意思?),使用它就相当于一些指针算术是这样的:

#include <iostream>

class A
{
    int a{};
public:
    int aa{};
    static ptrdiff_t getAOffset()
    {
        A instance;
        return reinterpret_cast<ptrdiff_t>(static_cast<const void*>(&instance)) - reinterpret_cast<ptrdiff_t>(static_cast<const void*>(&(instance.a)));
        //return offsetof(A, a); // "same" as this call to offset
    }

    int get() const
    {
        return a;
    }
};

class B: public virtual A
{
};

void update_field(char* pointer, ptrdiff_t offset, int value)
{
    int* field = reinterpret_cast<int*>(pointer + offset);
    *field = value;
}

void modify_a(B& instance)
{
    update_field(reinterpret_cast<char*>(dynamic_cast<A*>(&instance)), A::getAOffset(), 1);
}

int main()
{
    B instance;

    std::cout << instance.get() << std::endl;

    modify_a(instance);

    std::cout << instance.get() << std::endl;
}

我还做了一个不抱怨的大肠杆菌(迂腐),但仍然...... https://coliru.stacked-crooked.com/a/faecd0b248eff651

标准中是否有授权这一点的东西,或者这是在未定义的行为领域?很高兴看到标准之间是否存在差异。

4

0 回答 0