如何做静态断言指针转换是微不足道的? [英] How to do a static assert that a pointer cast is trivial?

查看:451
本文介绍了如何做静态断言指针转换是微不足道的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有这些类型:

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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆