有没有办法让 GCC/Clang 知道 C 中的继承?

2023-11-29

我正在编写一个 C 库,它使用一些简单的面向对象继承,如下所示:

struct Base {
    int x;
};

struct Derived {
    struct Base base;
    int y;
};

现在我想将 Derived* 传递给一个采用 Base* 的函数,如下所示:

int getx(struct Base *arg) {
    return arg->x;
};

int main() {
    struct Derived d;
    return getx(&d);
};

这是可行的,当然也是类型安全的,但编译器不知道这一点。有没有办法告诉编译器这是类型安全的?我在这里只关注 GCC 和 clang,因此欢迎特定于编译器的答案。我模糊地记得看到一些使用此方法执行此操作的代码__attribute__((inherits(Base))或诸如此类的事情,但我的记忆可能在撒谎。


这在 C 中是安全的,除了你应该将参数转换为Base *。禁止别名(或者更准确地说,标准 C 不支持别名)的规则位于 C 2011 6.5 中,其中第 7 段指出:

对象的存储值只能由具有以下类型之一的左值表达式访问:

— 与对象的有效类型兼容的类型,

这条规则阻止我们使用指针float,将其转换为指向的指针int,并取消引用指向的指针int访问float as an int。 (更准确地说,它不会阻止我们尝试,但它使行为变得不确定。)

您的代码可能违反了这一点,因为它访问了Derived对象使用Base左值。但是,将指针转换为Derived指向一个指针Base得到 C 2011 6.7.2.1 第 15 段的支持:

...指向结构对象的指针,经过适当转换后,指向其初始成员...

所以,当我们将指针转换为Derived指向一个指针Base,我们实际上拥有的不是指向Derived对象使用与它本身不同的类型(这是禁止的),但指向该对象的第一个成员的指针Derived使用其实际类型的对象,Base,这完全没问题。

关于编辑:最初我说函数参数将转换为参数类型。然而,C 6.5.2.2 2 要求每个参数都有一个类型,可以分配给一个具有其相应参数类型的对象(具有任何限定,如const已删除),并且 6.5.16.1 要求将一个指针分配给另一个指针时,它们具有兼容的类型(或满足此处不适用的其他条件)。因此,传递一个指针Derived指向一个带有指针的函数Base违反标准 C 约束。但是,如果您自己进行转换,则是合法的。如果需要,可以将转换构建到调用该函数的预处理器宏中,以便代码看起来仍然像一个简单的函数调用。

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

有没有办法让 GCC/Clang 知道 C 中的继承? 的相关文章

  • “构建”构建我的项目,“构建解决方案”则不构建

    我刚刚开始使用VS2010 我有一个较大的解决方案 已从 VS2008 成功迁移 我已将一个名为 Test 的控制台应用程序项目添加到解决方案中 选择构建 gt 构建解决方案不编译新项目 选择构建 gt 构建测试确实构建了项目 在失败的情况
  • GLKit的GLKMatrix“列专业”如何?

    前提A 当谈论线性存储器中的 列主 矩阵时 列被一个接一个地指定 使得存储器中的前 4 个条目对应于矩阵中的第一列 另一方面 行主 矩阵被理解为依次指定行 以便内存中的前 4 个条目指定矩阵的第一行 A GLKMatrix4看起来像这样 u
  • 在结构中使用 typedef 枚举并避免类型混合警告

    我正在使用 C99 我的编译器是 IAR Embedded workbench 但我认为这个问题对于其他一些编译器也有效 我有一个 typedef 枚举 其中包含一些项目 并且我向该新类型的结构添加了一个元素 typedef enum fo
  • 秒表有最长运行时间吗?

    多久可以Stopwatch在 NET 中运行 如果达到该限制 它会回绕到负数还是从 0 重新开始 Stopwatch Elapsed返回一个TimeSpan From MSDN https learn microsoft com en us
  • 查找c中结构元素的偏移量

    struct a struct b int i float j x struct c int k float l y z 谁能解释一下如何找到偏移量int k这样我们就可以找到地址int i Use offsetof 找到从开始处的偏移量z
  • Asp.NET WebApi 中类似文件名称的路由

    是否可以在 ASP NET Web API 路由配置中添加一条路由 以允许处理看起来有点像文件名的 URL 我尝试添加以下条目WebApiConfig Register 但这不起作用 使用 URIapi foo 0de7ebfa 3a55
  • 从Web API同步调用外部api

    我需要从我的 Web API 2 控制器调用外部 api 类似于此处的要求 使用 HttpClient 从 Web API 操作调用外部 HTTP 服务 https stackoverflow com questions 13222998
  • 在 Windows 窗体中保存带有 Alpha 通道的单色位图会保存不同(错误)的颜色

    在 C NET 2 0 Windows 窗体 Visual Studio Express 2010 中 我保存由相同颜色组成的图像 Bitmap bitmap new Bitmap width height PixelFormat Form
  • 如何从 appsettings.json 文件中的对象数组读取值

    我的 appsettings json 文件 StudentBirthdays Anne 01 11 2000 Peter 29 07 2001 Jane 15 10 2001 John Not Mentioned 我有一个单独的配置类 p
  • C++ OpenSSL 导出私钥

    到目前为止 我成功地使用了 SSL 但遇到了令人困惑的障碍 我生成了 RSA 密钥对 之前使用 PEM write bio RSAPrivateKey 来导出它们 然而 手册页声称该格式已经过时 实际上它看起来与通常的 PEM 格式不同 相
  • 创建链表而不将节点声明为指针

    我已经在谷歌和一些教科书上搜索了很长一段时间 我似乎无法理解为什么在构建链表时 节点需要是指针 例如 如果我有一个节点定义为 typedef struct Node int value struct Node next Node 为什么为了
  • 控件的命名约定[重复]

    这个问题在这里已经有答案了 Microsoft 在其网站上提供了命名指南 here http msdn microsoft com en us library xzf533w0 VS 71 aspx 我还有 框架设计指南 一书 我找不到有关
  • 如何在 C 中调用采用匿名结构的函数?

    如何在 C 中调用采用匿名结构的函数 比如这个函数 void func struct int x p printf i n p x 当提供原型的函数声明在范围内时 调用该函数的参数必须具有与原型中声明的类型兼容的类型 其中 兼容 具有标准定
  • 这些作业之间是否存在顺序点?

    以下代码中的两个赋值之间是否存在序列点 f f x 1 1 x 2 不 没有 在这种情况下 标准确实是含糊不清的 如果你想确认这一点 gcc 有这个非常酷的选项 Wsequence point在这种情况下 它会警告您该操作可能未定义
  • Windows 窗体:如果文本太长,请添加新行到标签

    我正在使用 C 有时 从网络服务返回的文本 我在标签中显示 太长 并且会在表单边缘被截断 如果标签不适合表单 是否有一种简单的方法可以在标签中添加换行符 Thanks 如果您将标签设置为autosize 它会随着您输入的任何文本自动增长 为
  • cmake 将标头包含到每个源文件中

    其实我有一个简单的问题 但找不到答案 也许你可以给我指一个副本 所以 问题是 是否可以告诉 cmake 指示编译器在每个源文件的开头自动包含一些头文件 这样就不需要放置 include foo h 了 谢谢 CMake 没有针对此特定用例的
  • C# 成员变量继承

    我对 C 有点陌生 但我在编程方面有相当广泛的背景 我想做的事情 为游戏定义不同的 MapTiles 我已经像这样定义了 MapTile 基类 public class MapTile public Texture2D texture pu
  • 是否可以在 .NET Core 中将 gRPC 与 HTTP/1.1 结合使用?

    我有两个网络服务 gRPC 客户端和 gRPC 服务器 服务器是用 NET Core编写的 然而 客户端是托管在 IIS 8 5 上的 NET Framework 4 7 2 Web 应用程序 所以它只支持HTTP 1 1 https le
  • 如何在文本框中插入图像

    有没有办法在文本框中插入图像 我正在开发一个聊天应用程序 我想用图标图像更改值 等 但我找不到如何在文本框中插入图像 Thanks 如果您使用 RichTextBox 进行聊天 请查看Paste http msdn microsoft co
  • 如何防止用户控件表单在 C# 中处理键盘输入(箭头键)

    我的用户控件包含其他可以选择的控件 我想实现使用箭头键导航子控件的方法 问题是家长控制拦截箭头键并使用它来滚动其视图什么是我想避免的事情 我想自己解决控制内容的导航问题 我如何控制由箭头键引起的标准行为 提前致谢 MTH 这通常是通过重写

随机推荐

  • PHP合并数组

    我一直在尝试 未成功 将多个数组的输出合并到一个数组中 我尝试过的一个例子是 data1 array cat goat data2 array dog cow print r array merge data1 data2 这工作得很好 但
  • 如何将 Unicode 字符作为 JSP/Servlet request.getParameter 传递?

    经过多次尝试和错误 我仍然无法找出问题所在 JSP Servlet 和数据库都设置为接受 UTF 8 编码 但即使如此 每当我对任何具有两字节字符 如破折号 的内容使用 request getParameter 时 它们都会被打乱为损坏的字
  • 有关内存映射接口的进一步问题

    我处理内存映射设备的 C 代码仍然存在一些问题 目前 我将写入的寄存器的地址空间声明为易失性 指针 我向它们写入数据 如下所示 volatile unsigned int wr register int 0x40000000 volatil
  • 如何在 iOS 上调用 Rootviewcontroller

    在我的 iOS 应用程序启动中检查用户是注册用户还是新用户 如 facebook 和 Skype 如果用户未注册 我正在导航应用程序以向我的应用程序委托注册屏幕 if user register RegisterViewController
  • Jquery Ajax POST 中出现 400 bad request 错误

    我正在尝试使用 Jquery 发送 Ajax POST 请求 但遇到 400 bad request 错误 这是我的代码 ajax type POST url http localhost 8080 project server rest
  • 在Lua中生成均匀随机数

    我正在用 Lua 编写马尔可夫链 其中一个要素要求我统一生成随机数 这是一个简化的例子来说明我的问题 example function x local r math random 1 10 print r return x r end ex
  • Servlet - 关闭连接但不关闭方法

    我必须实现将发送的服务 servlet 2 5 或 3 204在每个连接上编写代码但不关闭线程 我需要对收到的数据做一些事情 比如打开新连接 可以关闭连接但不能结束方法吗 或者在连接关闭时启动另一个方法 规范中尚不清楚 但它似乎可以在 To
  • 如何在服务器端获取客户端屏幕分辨率宽度/高度

    我可以使用客户端脚本 javascript 获取客户端屏幕分辨率 但我不想那样做 我也尝试过Request Browser ScreenPixelsWidth 但它总是返回固定宽度680 任何想法 客户端屏幕分辨率等信息是never在 HT
  • RDPSession ConnectToClient 意外终止

    我已经成功创建了一个桌面共享解决方案 其中 RDPViewer 连接到 RDPSession 这一切都很顺利 然而 现在我正在尝试相反的方法 使用 RDPViewer 的 StartReverseConnectListener 方法和 RD
  • 复制具有 unicode 名称的文件

    这应该是一个简单的脚本 import shutil files os listdir C for efile in files shutil copy efile D 它工作得很好 直到我在电脑上尝试使用 unicode 字符命名的文件 p
  • 具有地理位置策略的 AWS Cloudfront 与 Route53

    我们可以将CloudFront与Geolocation策略一起使用吗 或者CloudFront内部是否具有此功能并且可以单独使用来满足 或者 Route53 是一个正确的选择 同时需要为全球网站提供来自最近地理位置的请求以改善客户体验 另外
  • 为什么PHP不能创建777权限的目录?

    我正在尝试使用 PHP 和以下命令在我的服务器上创建一个目录 mkdir test 0777 但它并没有给出完整的权限 只有这些 rwxr xr x 该模式根据您当前的情况进行修改umask 即022在这种情况下 方式umask作品是一种减
  • Laravel 8:未定义方法“createToken”intelephense(1013)

    我对 PHP intelephense 方法有疑问创建令牌未定义 我不知道如何解决它 但是当我在邮递员中运行它时它就起作用了 我不知道为什么 vscode 不识别它 我还添加了使用 Laravel Passport HasApiTokens
  • HQL IN 运算符,枚举数组 ClassCastException

    这是我精简的类和枚举 class A Enumerated value EnumType STRING AType type enum AType X Y 如果我跑 query FROM A a WHERE a type type quer
  • Karate WebSocket 如何在一个会话中监听多个消息?

    对于我们的集成测试 我们有一个场景 我们想要监听由我们使用的环境预定义的一定数量的消息 我已经看到可以通过打开新连接来收听多个消息 但这并没有太大的灵活性 您是否阅读过文档 因为据我所知 如果您定义了 处理程序 函数 则可以对多个消息使用相
  • 在 R 中结合 grid_arrange_shared_legend() 和facet_wrap_labeller()

    我正在尝试结合grid arrange shared legend and facet wrap labeller 更具体地说 我想绘制一个包含两个 ggplot 图形的图形 每个图形都有多个面板 并且有一个共同的图例 我还想将部分刻面条标
  • 使用批处理文件并排合并 csv 文件[重复]

    这个问题在这里已经有答案了 我有一个非常基本的批处理命令来将 csv 文件合并在一起 但是我需要将它们合并 以便各列并排而不是继续 每个文件上的记录数量始终相同 这是我到目前为止的基本代码 COPY File1 csv File2 csv
  • 尝试使用 XML 配置关闭一个 URL 的安全性

    我检查了几个博客 doc stackoverflow 论坛条目 但我仍然不知道我做错了什么 我想向任何人授予对 URL 的访问权限 这permitAll不起作用 因为我有自定义过滤器 所以我想创建一个单独的http元素并使用security
  • 基于 boost::asio 的慢速 http 客户端 - (分块传输)

    我正在使用以下代码 取自 boost 教程 从服务器获取 json 字符串 问题是它需要一些时间来执行 即超过 2 秒才能完成 并且客户端和服务器都在本地主机上 如果我删除程序的最后两行 即此时 while boost asio read
  • 有没有办法让 GCC/Clang 知道 C 中的继承?

    我正在编写一个 C 库 它使用一些简单的面向对象继承 如下所示 struct Base int x struct Derived struct Base base int y 现在我想将 Derived 传递给一个采用 Base 的函数 如