c – 如何进行静态断言,指针转换是微不足道的?

c – 如何进行静态断言,指针转换是微不足道的?,第1张

概述假设我有这些类型: struct A { int a;};struct B { int b;};struct C : public A, public B { int c;}; 可以将C *指针强制转换为A *指针,而根本不调整实际地址.但是当C *被转换为B *时,该值必须改变.我想确保我所拥有的两个相关类型可以在不改变地址的情况下相互转换(即没有多重继承, 假设我有这些类型:
struct A {    int a;};struct B {    int b;};struct C : public A,public B {    int c;};

可以将C *指针强制转换为A *指针,而根本不调整实际地址.但是当C *被转换为B *时,该值必须改变.我想确保我所拥有的两个相关类型可以在不改变地址的情况下相互转换(即没有多重继承,或者基类是派生类的第一个基础).这可以在运行时检查,例如像这样

assert(size_t(static_cast<A*>((C*)0xF000) == 0xF000);assert(size_t(static_cast<B*>((C*)0xF000) != 0xF000);

这样可行.但是这个信息在编译时是已知的,所以我正在寻找一种方法来对它进行编译时断言.将上述转换为静态断言的明显方法(例如,用BOOST_STATIC_ASSERT替换断言)将错误“强制转换为除积分或枚举类型之外的类型”不能出现在带有g 4.2的常量表达式中.

便携性不是很重要.使用gcc扩展或Hacky模板技巧都可以.

更新:发现之前已经问过几乎相同的问题:C++,statically detect base classes with differing addresses?.使用offsetof()也是唯一有用的建议.

解决方法 “我想确保两个相关类型可以相互转换而不需要更改地址(即没有多重继承,或者基类是派生类的第一个基础).”

你的“IE”是不对的.例如,Derived的前4个字节完全有可能是vtable指针,即使Base不是多态的.是的,如果(1)第一个基础子对象位于偏移0处,并且(2)vtable指针位于偏移0处,则C编译器更容易.但是这两个目标本质上是不一致的,并且没有明显更好的选择.

现在,第一部分可以在理论上进行测试.对于标准布局类型,offset_of(Base,first_member)和offset_of(Derived,first_member)没有区别.但实际上,offset_of对于有趣的类型不起作用;这是UB.此检查的重点是检查类型,因此对于非标准布局类型,它应该可靠地失败.

总结

以上是内存溢出为你收集整理的c – 如何进行静态断言,指针转换是微不足道的?全部内容,希望文章能够帮你解决c – 如何进行静态断言,指针转换是微不足道的?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/langs/1239448.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存