Dan*_*our 18 c++ pointers language-lawyer c++11
假设有一个结构
struct Thing {
int a;
bool b;
};
Run Code Online (Sandbox Code Playgroud)
我得到一个指向b该结构成员的指针,比如某些函数的参数:
void some_function (bool * ptr) {
Thing * thing = /* ?? */;
}
Run Code Online (Sandbox Code Playgroud)
如何获取指向包含对象的指针?最重要的是:如果不违反标准中的某些规则,那就是我需要标准定义的行为,而不是未定义的行为,也不是实现定义的行为.
作为旁注:我知道这可以避免类型安全.
Som*_*ude 19
如果你确定指针真的指向b结构中的成员,就像有人那样
Thing t;
some_function(&t.b);
Run Code Online (Sandbox Code Playgroud)
然后你应该能够使用offsetof宏来获得指向结构的指针:
std::size_t offset = offsetof(Thing, b);
Thing* thing = reinterpret_cast<Thing*>(reinterpret_cast<int8_t*>(ptr) - offset);
Run Code Online (Sandbox Code Playgroud)
请注意,如果指针ptr实际上没有指向Thing::b成员,那么如果使用指针,上面的代码将导致未定义的行为thing.
void some_function (bool * ptr) {
Thing * thing = (Thing*)(((char*)ptr) - offsetof(Thing,b));
}
Run Code Online (Sandbox Code Playgroud)
我认为没有UB。
X* get_ptr(bool* b){
static typename std::aligned_storage<sizeof(X),alignof(X)>::type buffer;
X* p=static_cast<X*>(static_cast<void*>(&buffer));
ptrdiff_t const offset=static_cast<char*>(static_cast<void*>(&p->b))-static_cast<char*>(static_cast<void*>(&buffer));
return static_cast<X*>(static_cast<void*>(static_cast<char*>(static_cast<void*>(b))-offset));
}
Run Code Online (Sandbox Code Playgroud)
首先,我们创建一些可以容纳的静态存储X.然后我们得到X缓冲区中可能存在的对象的地址,b以及该对象的元素的地址.
回到char*,我们可以得到bool缓冲区内的偏移量,然后我们可以使用它来调整指向真实bool的指针返回指向包含的内容X.