为什么C ++在嵌入式系统设计中是C的可行替代品

news2024/12/29 11:41:46

你是一名。你知道C是适合该工作的语言,尽管有时维护周期可以重复很长时间。有时你会感到that琐,就像在编码自动机一样,反复在结构上创建基本迭代,这些结构与上周或上个月的结构非常相似。

你已经听说过C ++作为一种功能强大的语言的销售趋势,但是你也听说过有关C ++巨大足迹的恐怖故事,这使C ++成为嵌入式应用的不二之选。此外,它是如此复杂:必须确实很难使用。

这有一个熟悉的戒指吗?嵌入式开发市场嵌入式开发市场涵盖了广泛的应用领域,包括汽车,医疗,国防和电信。尽管C作为嵌入式开发的强大语言嵌入式开发的强大语言无疑享有良好的声誉,但C ++却没有那么广泛的吸引力。在当今功能强大且复杂的C ++环境中,这通常是不正确的信念。

为什么C ++可以替代C?作为一种语言,它当然是从C语言的根源发展而来的。仅使用aC ++编译器重新编译C项目将产生更严格的代码类型检查(可能需要先克服一些声明上的不兼容性)。

一旦掌握了其核心功能,C ++就可以提供更大的数据抽象,这对于更大,更复杂的软件系统来说是一个重要的目标。面向对象(OO)使这一抽象更进一步,你可以用类功能替换全局“工作者”功能。

模板可能是抵制C ++使用的最大恐惧因素,并且经常被引用为大型代码膨胀经验的原因或推测。但是,实际上,精心设计的模板代码提供了一种优雅的方式来一致地处理各种数据类型。C ++的StandardLibrary是此类通用编程风格的广告。

异常处理是另一个遭受FUD(恐惧,不确定性和怀疑)困扰的领域。许多C软件系统中的异常通常是手动的编程任务。可以用更优雅的基于C ++异常的解决方案替换此异常处理机制,尽管需要付费。

与往常一样,只有在对开发团队进行需求更改时,这种优雅的解决方案才能得到应有的认可。精心设计的基于对象的设计在这种情况下可以适应的速度部分归因于更好的实现抽象和隐藏。

编译器性能

坦率地说,比较C和C ++编译器实现可能令人讨厌。从这种苹果与橘子的比较中很难获得科学的结果。

有趣的新闻组讨论报告了C ++实现的空间和性能效率损失在8%到30%之间。当然,对于使用相同Clibrary的完全相同的代码,我们希望使用相同的二进制代码。

在其产生的过程中,毫无疑问在速度方面,特别是在可执行和运行时空间需求方面,C ++性能的经验很差。在C ++的采用初期,这些担忧导致了有趣的行业形成。

十年前,主要是日本嵌入式系统提供商的合作提出了一种严格受限的C ++语言语言环境,以满足嵌入式需求。该概念禁止使用C ++语言,包括异常处理,运行时类型信息,命名空间,模板,多重继承和虚拟函数。

其理由有两个主要方面。首先是消除导致可怕的“代码膨胀”的语言构造。第二个目的是从学习的角度简化C ++语言,也许是因为嵌入式工程师的OO经验水平较低。根本有缺陷

但是,在充分尊重作者的前提下,EmbeddedC ++的方法似乎存在根本缺陷。C ++语言委员会的勤奋工作的成员一定听说过放弃其精心设计的标准C ++语言的全部内容的提议,对此感到灰白。

他们对该建议的集体回应是开始审查该语言及其最受欢迎的实现(编译器和机器环境)中的实际性能问题。

结果是C ++标准委员会发布的一份全面报告,内容涉及完整C ++语言每个主要功能的性能预期。报告中有一个小节介绍了每个功能的性能和空间效率(静态和运行时)。本文总结了最有趣的功能的发现。

a)命名空间:与使用命名空间没有空间或时间开销。它们仅在编译时影响名称查找规则。命名空间的主要优点是提供了一种在大型项目中对名称进行分区的机制,以避免名称冲突。顺便说一句,using指令通过将所有未限定的标识符移动到当前名称空间中,避免了在使用显式名称空间限定时进行额外的键入工作。

b)TypeConversions: C ++带有C样式转换符号,但是通过四个适用于不同转换情况的newoperator支持更安全和显式的转换。对于这些新样式转换操作符中的三个(const_cast,static_cast和reinterpret_cast),不涉及性能。

实际上,编译器在生成目标代码时通常会将转换符号转换为这些新的类型转换运算符之一。如果需要的转换需要运行时类型信息(RTTI)机制(例如,在类层次结构中进行交叉转换),则只有dynamic_cast可能会涉及额外的开销,我们将在后面介绍。

c)ClassRepresentation: 与C的structand全局函数等效项相比,基本的类功能并不感到任何空间或速度开销,这有些令人惊讶。这是因为非虚拟函数和静态数据成员与类定义一起存储,而不是存储在类的对象中。

成员函数调用还有一个额外的隐式指针参数,必须指向类对象(* this)。另一方面,独立的函数调用通常需要通过等效的显式指针参数将操作数据明确地传递给它们。

d)VirtualFunctions: 虚拟函数会产生明确定义的成本,该成本基于基础操作:索引到函数指针数组中。这是一种在Ccode中很常见的实现技术,但在虚拟函数范式中表达得更为优雅。

在某些情况下,使用虚函数可能会导致“代码膨胀”。如果包含虚拟函数的类模板针对各种类型进行了专门化,则每个专门化都将保留重复的成员函数及其相关的支持结构,包括虚拟表。

通常,这将导致过多的目标代码,因为当前的链接器/优化器技术不够成熟,无法识别这种情况。为避免此问题,你可以将通用代码(不依赖于实例化类型)移出类模板并移入非模板帮助器函数,或者将功能性从模板类移至非模板基类。

e)FunctionInlining: 就提高性能效率而言,应避免使用函数调用。C ++的内联功能为编译器提供了可以内联到其调用位置的函数的提示。编译器没有义务接受此提示。先进的优化技术可以自动识别和删除较小且不太复杂的函数调用,而无需代码明确提供内联提示。但是,迄今为止的经验表明,隐式内联不会产生一致的好处,因此应该使用显式内联关键字。

f)虚拟基类(VBC):在非虚拟继承中,成员函数调用执行简单的常量调整。与VBC的本质区别在于成员函数需要在运行时执行查找,以发现应激活继承树中的哪个类函数。与非虚拟案例相比,这涉及大约15%的额外开销。

但是,通过另一个功能来模拟虚拟呼叫的功能也会带来成本。实现在组成类周围传递的接口类的另一种技术本身确实需要在访问中使用间接方式,从而导致随之而来的成本和开销。

g)运行时类型信息:

RTTI用于询问对象的类型,它也是dynamic_cast功能基础结构的一部分。为了说明其性能,请考虑使用dynamic_cast的应用程序:查找对象的vtable,找到该对象的派生对象最多的对象,使用该对象的type_info对this指针执行所需的调整。

h)异常处理: C ++的异常处理功能在运行时需要类型信息,并且与RTTI结构部分重叠并扩展了RTTI结构。但是,任何手动编码备选方案都必须考虑编码风格,错误处理例程的完整覆盖,线程安全性,运行时系统开销以及处理错误的开销。考虑相关的开销,运行时开销和代码维护开销可以进行异常处理合理的选择。

i)模板:就空间成本而言,模板是C ++最受人谴责的功能之一。当类和函数模板为具有不同参数的每个实例生成一组新的代码和数据时,就会出现代码膨胀。

对相同专业化的多个实例化与许多不同专业化进行的测试表明,性能结果差异很大,这表明编译器有一些方法可以满足该领域的优化目标。实施优化

通过启用某些功能(尤其是部分专业化功能),编译器可以允许图书馆供应商实施优化以克服此问题。开发人员可以通过通用类模板路由所有实例化请求,例如通过对基于void *的单个专业化使用通用类模板,来部署避免多个专业化的技术。

尽管此分析可能会使你更熟悉C ++作为一种开发语言,但它本身并不能帮助你创建良好,可靠且尤其是高性能的C ++代码。

对于C ++语言中的优化问题,有很多建议,包括初始化优先于赋值,避免不必要的转换,避免临时对象的创建(参数传递,函数返回和表达式)以及内联的明智使用。除了基于语言的优化之外,还建议正确使用C ++的出色库。

编码标准实施(CSE)工具的使用提供了一个有用的安全网,该网络可让你自由创建C ++代码,但在编写可疑代码时会及时发出警告。例如,PRQA的QAC ++ advancedanalyzer工具标记了不可移植,难以维护,过于复杂,不符合ISO或以任何可能引起问题的方式编写的代码。

消息浏览器在整个项目的源代码上显示警告消息。这些在所有源文件中进行了分类和分组。浏览器链接到有用的附加信息,以及有关分析仪识别出的编码违规的建议。

可以按文件或项目分析源代码,以识别潜在的危险语言用法,以防止错误爬入你的系统。该分析仪能够找到代码中的晦涩错误,从而大大减少了调试时间。

但是,让我们回到C开发人员的心态。通常,人们认为使用C ++开发与传统的C开发相比需要采取截然不同的方法。如果我们研究两种典型的实现技术,我们可能得出不同的结论。

C中的多态性

一条记录需要存储不同类型的数据,其定义可能如下所示:

然后,对该记录进行操作的所有代码都必须检查其代表的数据类型:

但这看起来很像多态概念。成员类型对应于类vtable指针,而switch语句中的代码段对应于一组虚函数。

考虑到使用此记录时此类转换语句的泛滥,多态替代方案更加优雅且易于维护。甚至没有最大填充类型的数据填充的好处,就像这里必须发生的那样。

C中的代码膨胀在

典型的C项目中,你经常会看到迭代代码,例如:

C ++库通过将丰富迭代功能放入其容器类集中来针对这种类型的重复代码。与通常使用手工编码的替代方法相比,它提供了更易于维护,紧凑且最可能更快的实现。嵌入式学习路线

因此,性能能力的这种证明也许并不会导致你立即将嵌入式开发转换为C ++语言-毕竟,选择轻松进行并非易事。但是,随着项目规模的扩大,它们越来越需要精心设计和管理。

在这种情况下,C ++完全可以替代C。基于PRQA自身的经验,C ++在可维护性以及对变更和扩展要求的响应方面提供了很高的回报。

在嵌入式开发的更严格要求下,这些研究结果表明,只要稍加注意和注意,并借助CSE工具的附加安全网络,C ++就可以提供很多功能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1003103.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【AI绘画接口】Midjourney是什么?Midjourney有官方接口吗?

什么是 Midjourney? 随着AI技术的发展,AI聊天、AI绘画都从小众尝鲜逐渐应用到了生产当中。现在市面上的绘画AI并不少,而 Midjourney 是其中最好用的之一。我们只需要输入一些提示词,Midjourney 就能根据输入的提示词自动生成符合…

怎么找回回收站删除的文件?轻松恢复数据,就看这3个方法!

“求助求助!回收站删除的文件还有找回来的机会吗?一不小心就把回收站中的文件删除了,现在不知道该如何是好了,希望热心的网友们可以帮帮我!” 大家都知道,电脑有一个功能叫回收站,系统会将我们删…

代码随想录 -- day49 -- 121. 买卖股票的最佳时机 、122.买卖股票的最佳时机II

121. 买卖股票的最佳时机 动态规划: dp[i][0] 表示第i天持有股票所得最多现金,dp[i][0] 表示第i天持有股票所得最多现金。 第i-1天就持有股票,那么就保持现状,所得现金就是昨天持有股票的所得现金 即:dp[i - 1][0]第…

echarts折线图每段显示不同的颜色

效果图 配置项: zqChartFour: {title: {text: "一天用电量分布",subtext: "纯属虚构",},tooltip: {trigger: "axis",axisPointer: {type: "cross",},},toolbox: {show: true,feature: {saveAsImage: {},},},xAxis: {type:…

Linux 中nc指令的使用总结

nc指令概述用法一:端口扫描用法二:命令行中发送和接收数据用法三:建立双方通信 nc指令概述 nc 是 Linux 系统中的 netcat 命令之简称,它是一个强大的网络工具,可以用于创建 TCP/UDP 套接字连接。常见的其用法模板可定…

目标检测中生成锚框函数详解

将设一张图片,宽和高为2,2 X torch.rand(size(1,3,2,2)) Y generate_anchors(X,sizes[0.75,0.5,0.25],ratios[1,2,0.5])锚框中心点的设置 # 为每个像素可以生成 nm-1个锚框,整个图像生成 wh(nm-1) def generate_anchors(data,sizes,ratios): # 书上的…

重磅预告 |第十二届中国智能产业高峰论坛9月16日在昌开幕,集团董事长李火亮任专题联席主席,出席本次活动

在这个数字化、智能化社会经济高速迭代的时代,每一次技术的进步都预示着一个全新的未来。在此背景下第十二届中国智能产业高峰论坛即将拉开帷幕。9月16日-9月18日高峰论坛在中国南昌举行,拓世科技集团董事长李火亮将亲身出席本次活动,与众多领…

解决:AD装配输出拾放文件出现闪退问题

PCB在装配输出过程中,需要导出拾放文件,但是今天每次执行这个过程,AD软件就会直接闪退。 重启AD把项目管理器中没有关掉的一系列乱七八糟文件手动关闭关闭AD软件再次重启AD,打开项目重新导出。

YOLOv5 加入SE注意力机制

步骤1:在common.py中添加SE模块 class SE(nn.Module): def __init__(self, c1, c2, r16): super(SE, self).__init__() self.avgpool nn.AdaptiveAvgPool2d(1) self.l1 nn.Linear(c1, c1 // r, biasFalse) self.relu nn.ReL…

付费咨询擅长领域

曾获中国电机工程学报优秀审稿专家,控制与决策审稿专家,系统工程与电子技术审稿专家,计算机科学审稿专家,Mechanical System and Signal Processing审稿专家。 擅长现代信号处理(小波分析类,模态分解类&…

SAP 自定义权限对象开发与使用

如何自定义一个权限对象,然后分配到对应的权限角色中,进行用户权限的控制? 具体实现步骤如下: 1. 创建数据元素 进入事务码: SE11 2. 创建权限字段 进入事务码SU20 3. 创建权限对象类以及权限对象 事务码&#xf…

redis集群的维护(redis-cli --cluster 命令用法)

目录 前言 1、 --cluster create 创建集群 2、--cluster check 检查集群 3、--cluster info 查看集群 4、--cluster fix 修复集群 5、--cluster rehard 迁移槽位 6、 --cluster rebalance 平衡集群 7、 --cluster add-node 集群扩容 8、--cluster del-node …

实现读写分离(MySQL主从数据库)

读写别离(Read/Write Splitting)。 1.原理: 让主数据库(master)处理事务性增、改、删操作(INSERT、UPDATE、DELETE),而从数据库(slave)处理SELECT查询操作。 …

论文复制ChatGPT按钮被发表,撤回后再曝多个类似案例;Midjourney 生成大师级的人像

🦉 AI新闻 🚀 论文复制ChatGPT按钮被发表,撤回后再曝多个类似案例 摘要:一篇物理论文复制了ChatGPT按钮内容,经过两个月同行评审并在杂志上发表。这一现象被知名打假人发现后,发表商决定撤回该论文。此外…

doccano 文本标注工具使用

最近在做面向大模型的文本标注工作,涉及到多人协同的问题,因此用到了doccano工具。 这个工具可以使用docker进行安装,安装之后的启动也都比较简单。 关于基础使用(例如管理员登录、新建任务、上传数据集等)&#xff…

推荐 4 个本周 火火火火 的开源项目

本期推荐开源项目目录: 1. 一个集成了主流 AI 大模型的 APP 2. 模拟人类行为的小镇 3. 离线 OCR 软件 4. 流程图编辑框架 01 一个集成了主流 AI 大模型的 APP 该开源项目集成了主流的大语言模型、绘图模型,基于Flutter开发,支持问答聊天、文生…

10个值得收藏的3D任务角色下载网站

每个人都喜欢免费的东西。 无论是免费的 3D 角色还是游戏资产,我们都喜欢它们。 以下是可以为你的游戏获取免费 3D 角色的前 10 个网站的列表。 你可以将它们用于多种用途,例如 3D 打印或动画剪辑。 如果需要将下载的3D模型转换为其他格式,可…

科技资讯|苹果虚拟纸可在Vision Pro中为广告、书籍等提供MR内容和动画

近日,美国专利商标局正式授予苹果一项与虚拟纸张相关的专利。这是与虚拟纸张这项发明相关的第二项专利,鉴于苹果 Vision Pro 将于明年上市,那么我们离苹果实现虚拟纸张的发明又近了一步。 虚拟纸张将能够包含 2D、3D 和动画等 MR内容&#…

移远通信一站式Matter智能照明/电工解决方案,让家居生活互联互通更便捷

从原始时期的钻木取火,到19世纪爱迪生发明电灯,人类对于“光亮”的追求从未停止。而伴随着社会经济的发展,人们对于照明等家居生活的追求开始从“物质层面”逐步向“精神层面”转变,智能家居成为了当下社会智能技术走向大众的重要…

crAPI靶场学习记录

靶场搭建 [靶场下载地址](我fork了一份) docker安装,笔者是用的wsldocker. [lab0:**初始账户 **] 注册一个账户,邮箱为[APIqq.com],密码为Admin123 登陆后访问对应IP的8025端口,接收邮件获取车辆信息。 [lab1:**访问其它用户车…