如何静态断言指针转换是微不足道的?

2024-01-22

假设我有以下类型:

struct A {
    int a;
};

struct B {
    int b;
};

struct C : public A, public B {
    int c;
};

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

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

这样可行。但这些信息在编译时是已知的,所以我正在寻找一种方法来对其进行编译时断言。将上述内容转换为静态断言的明显方法(例如替换assert with BOOST_STATIC_ASSERT使用 g++ 4.2 给出错误“对除整型或枚举类型之外的类型的强制转换不能出现在常量表达式中”。

便携性并不是太重要。使用 gcc 扩展或 hacky 模板技巧都可以。

Update:发现之前几乎有人问过同样的问题:C++,静态检测具有不同地址的基类? https://stackoverflow.com/questions/1131643/c-statically-detect-base-classes-with-differing-addresses. Using offsetof()也是唯一有用的建议。


“我想确保两个相关类型可以在不更改地址的情况下相互转换(即没有多重继承,或者基类是派生类的第一个基类)。”

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

现在,第一部分可以在理论上进行测试。对于标准布局类型,不会有什么区别offset_of(Base, first_member) and offset_of(Derived, first_member)。但在实践中,offset_of不适用于有趣的类型;是UB。此检查的重点是检查类型,因此对于非标准布局类型,它应该可靠地失败。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何静态断言指针转换是微不足道的? 的相关文章

随机推荐

  • JavaFX 初始化方法中的 NullPointerException

    我有控制器 我尝试从电子邮件服务器获取 INBOX 文件夹 下载下来就一切正常了 我可以将此数据 电子邮件主题 发件人 日期 放入 TableView 中 但是 仅当我等待负责在 TableView 中设置此数据的线程时 代码 The ta
  • 计算 iPhone 和门之间的距离,了解它们的物理宽度

    我有这样的场景 我知道 iPhone 屏幕的物理 不仅仅是像素 尺寸 我还知道门的宽度 现在 如果我打开 iPhone 摄像头 使用 UIImagePicker 或其他 并且我处于门的宽度完全适合摄像头宽度的位置 并且 iPhone 完全垂
  • 如何从 .jar 文件引用 .dll

    我有一个应用程序 它使用 jar 中的方法来调用 dll 这在我的机器上工作得很好 当应用程序解包或作为 jar 本身运行时 但是当 application jar 在另一台机器上运行时 外部 dll 位于系统路径上 它无法运行 dll 文
  • 我应该重载 == 运算符吗?

    如何 运算符在 C 中真的起作用吗 如果它用于比较类的对象A 它会尝试匹配所有A的属性 还是会寻找指向同一内存位置 或者可能是其他位置 的指针 让我们创建一个假设的例子 我正在编写一个利用 Twitter API 的应用程序 它有一个Twe
  • 使用生成器解析 fasta 文件( python )

    我正在尝试解析一个大的 fasta 文件 但遇到内存不足错误 一些改进数据处理的建议将不胜感激 目前 程序正确打印出名称 但是部分通过文件我得到了 MemoryError 这是发电机 def readFastaEntry fp name s
  • 如何在 iPhone 上将 sqlite ReadOnly 更改为 ReadWrite?

    我将我的应用程序部署到我的 iPhone 上并得到 Unknown error calling sqlite3 step 8 attempt to write a readonly database eu关于插入 更新语句 在模拟器上一切都
  • 如何设置 pageToken 以通过 Java SDK 从 Google Cloud Storage 获取项目列表?

    我想设置 pageToken 以获取存储在 Google Cloud Storage 中的项目 我正在使用适用于 Java v1 19 x 的 Google API 客户端库 我不知道从文件路径 或文件名 生成 pageToken 存储桶中
  • SQl 从表中删除前 100 条

    我正在尝试删除表中除最近 3 000 个项目之外的所有项目 该表有 105 000 条记录 我正在尝试此操作 但生成了错误的语法错误 delete tRealtyTrac where creation in select top 10300
  • 列出 iPhone 上本地网络上的所有计算机名称

    有没有办法在 iPhone 上的表格视图中获取并显示本地网络上的计算机名称 包括 IP 地址 列表 所有电脑包括mac windows linux等 提前致谢 您需要执行的操作分为两部分 扫描本地网络以查找所有活动主机并对其 IP 地址进行
  • 值未显示在选择按钮中

    我试图在选择按钮中获取选项 但它没有显示 我的代码如下 索引 html
  • 我如何获得在 ASP.NET MVC 表单中定义 n 次的值?

    我有一个表单 用户使用添加另一个文本框并填写它们来填写信息 n 次 我把它们命名为 textbox 1 textbox 2 现在我如何获取以 textbox 1 开头的所有表单值 任何想法在 ASP NET MVC 中做到这一点 您可以使用
  • 如何使用 C++ 列出 Windows 中的子目录?

    如何使用 C 列出 Windows 中的子目录 使用可以跨平台运行的代码会更好 这是我的问题解决方案 但它是仅限 Windows 的解决方案 我想使用跨平台解决方案 但不使用 boost include
  • 反射获取FieldInfo对象的类型?

    大家好 我需要访问课程某类声明的 Wrapper 类中有一个私有字段 到目前为止 使用反射我已经能够获取私有字段成员 我如何将其转换回其原始类型 以便我可以访问它的属性和其他成员 internal class Program private
  • 架构更改后 Firedac 查询字段列表未更新

    我正在 SQL 中创建一个临时表 然后向其中添加一个新字段 Firedac 似乎正在缓存该临时表的字段列表 以下代码给出 FDQuery5 未找到字段 可用 FDQuery5 Connection FDConnection1 FDConne
  • 正确使用session_set_cookie_params

    我正在尝试实现一个具有 记住我 功能的登录系统 这是我的登录页面 http pastebin com q6iK0Mgy http pastebin com q6iK0Mgy 在此 我尝试使用 session set cookie param
  • Django 无法使用原子事务的 try-exception 块回滚

    我在 Django 中的视图之一对 6 7 个表执行保存操作 我希望这些事务是原子的 即如果第五个或第六个事务失败 我想回滚所有以前的保存 该视图包含一个 try except 块来处理引发的异常 它看起来像这样 transaction a
  • 与 pip install 相比,pipenv install 有什么区别?

    使用有什么区别pipenv install
  • 使用 VARCHAR2 列中的语句进行查询

    有没有办法将 select 语句包含在WHERE子句 包含在表中的语句 例如下表 CREATE TABLE test tab date column DATE frequency NUMBER test statement VARCHAR2
  • devise 中的 form_for 是如何工作的?

    Rails g devise views 命令生成该视图 h2 Sign up h2 div br div div br div
  • 如何静态断言指针转换是微不足道的?

    假设我有以下类型 struct A int a struct B int b struct C public A public B int c A C 指针可以转换为A 指针根本不调整实际地址 但当C 被投射到B 该值必须改变 我想确保我拥