如何做静态断言指针转换是微不足道的? [英] How to do a static assert that a pointer cast is trivial?
问题描述
假设我有这些类型:
struct A {
int a;
};
struct B {
int b;
};
struct C : public A, public B {
int c;
};
A C *
A *
指针,而根本不调整实际地址。但是当 C *
被转换为 B *
时,值必须更改。我想确保两个相关类型我可以相互转换,而不改变地址(即没有多重继承,或者基类是派生类的第一个基础)。这可以在运行时被检查,例如。像这样
A C*
pointer can be cast to A*
pointer without adjusting the actual address at all. But when C*
is cast to B*
, the value must change. I'd like to ensure that two related types I have can be cast to each other without a change in address (i.e. that there is no multiple inheritance, or that the base class is the first base of the derived class). This could be checked at run-time, e.g. like so
assert(size_t(static_cast<A*>((C*)0xF000) == 0xF000);
assert(size_t(static_cast<B*>((C*)0xF000) != 0xF000);
这是可行的,但是这个信息在编译时是已知的,所以我正在寻找一种方法来做一个编译时断言。将上面的代码转换为静态断言的明显方法(例如替换 assert 与
BOOST_STATIC_ASSERT
给出错误转换为非整数或枚举类型的类型不能出现在常量表达式与g ++ 4.2。
That works. But this information is known at compile time, so I'm looking for a way to do a compile-time assert on it. The obvious ways of converting the above to a static assert (e.g. replace assert
with BOOST_STATIC_ASSERT
give the error "a cast to a type other than an integral or enumeration type cannot appear in a constant-expression" with g++ 4.2.
可移植性并不重要,使用gcc扩展或模板技巧都会很好。
Portability isn't too important. Using gcc extensions, or hacky template tricks would all be fine.
更新:发现之前已提出过几乎相同的问题: C ++,静态地检测具有不同地址的基类?。使用 offsetof()
p>
Update: Found that almost the same question has been asked before: C++, statically detect base classes with differing addresses?. Using offsetof()
is the only useful suggestion there too.
推荐答案
根据MSalters的建议,以及 C ++,静态地检测具有不同地址的基类?,这里是我能得出的最接近的答案。这可能是gcc特定的,需要知道基类的一些成员:
Based on a suggestion from MSalters, and an answer from C++, statically detect base classes with differing addresses?, here is the closest thing to an answer I can come up with. It's probably gcc-specific, and requires knowing some member of the base class:
#pragma GCC diagnostic ignored "-Winvalid-offsetof" // To suppress warning.
BOOST_STATIC_ASSERT(offsetof(C, a) == offsetof(A, a));
BOOST_STATIC_ASSERT(offsetof(C, b) != offsetof(B, b));
#pragma GCC diagnostic warn "-Winvalid-offsetof"
显然这是不方便的,可怕的(需要知道一个成员并关闭警告)。
Obviously this is both inconvenient and scary (requires to know a member and to turn off a warning).
这篇关于如何做静态断言指针转换是微不足道的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!