我放了标签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
标准中是否有授权这一点的东西,或者这是在未定义的行为领域?很高兴看到标准之间是否存在差异。