【发布时间】:2013-12-22 02:22:29
【问题描述】:
我的情况如下:
//This is Public
class B{/*usefull stuff*/};
B*f();
void g(B*b)();
//Those classes are only declared the translation unit of f and g.
class Whatever1{/*Implementation details only useful to f and g*/};
class Whatever2{/*Implementation details only useful to f and g*/};
class A{
public:
Whatever1 w1;
Whatever2 w2;
B b;
};
在函数g中,我想将参数(指向B的指针)转换为指向A的指针。
B 实例总是包装在 A 实例中。
我最终得到了这个:
ptrdiff_t lag(){
A a;
return (char*)&a.b-(char*)&a;}
void g(B*b){
A*a=(A*)((char*)b-lag());
//Work with a
}
这个解决方案让我很不舒服。
像这样进行偏移计算是否 100% 正确且可移植?
它会以任何方式触发未定义行为吗?
编辑:std::is_standard_layout::value 为 1。
【问题讨论】:
-
我不知道它是否会起作用(它对我发出“未定义的行为”),但您可能需要检查
offsetof。 -
另外,这个问题有the XY problem的味道。也就是说,您向我们展示了一个解决方案,但没有告诉我们该解决方案试图解决的问题。
-
如果你必须问某事是否是 UB,它可能是(如果你不必问,那么它可能是无论如何)
-
是的,
offsetof是要走的路。它恰好在您的原始代码也有效的情况下有效,但是使用 GCC 的offsetof实现(可能还有其他一些),如果将它与无效的类型一起使用,您将获得编译时诊断。 -
@CatPlusPlus 我不确定未定义的行为。当他做减法时,他在
char*上做;指向对象所在的底层字节数组的指针。如果要将其用于低级代码,尤其是在内存管理系统本身的实现中,这是 C++ 的一个基本特性。 (我确实认为它可能在这里被滥用了。)
标签: c++ c++11 offset language-lawyer undefined-behavior