\ \ begingroup \美元

在这里和其他地方,这是一个常见的问题。c++适合于嵌入式系统吗?

微控制器?操作系统?烤面包机吗?嵌入式电脑?

面向对象编程在微控制器上有用吗?

c++是否将程序员从硬件中移除得太远而无法提高效率?

Arduino的c++(没有动态内存管理,模板,异常)应该被认为是“真正的c++”吗?

(希望这个维基将成为一个地方来遏制潜在的圣战)

\ \ endgroup \美元
9
  • 8
    \ \ begingroup \美元 一个小问题,当你说嵌入式,你是指微控制器吗?微处理器吗?嵌入式x86 /嵌入式PC? \ \ endgroup \美元- - - - - -J. Plfer. 6月15日16:07
  • 1
    \ \ begingroup \美元 我并不想挑起圣战;目的是了解你反对的理由。 \ \ endgroup \美元- - - - - -J. Plfer. 6月15日10点16分08分
  • 2
    \ \ begingroup \美元 在之前的几个问题中都提到过,所以我想中心的地方会比较好。 \ \ endgroup \美元- - - - - -托比Jaffey 16:10 16:13
  • 4
    \ \ begingroup \美元 c++ vs embedded是一个有争议的话题。我有一个强烈的观点,但我认为这是不公平的提出一个问题和比赛得分。我希望社区wiki能使讨论更加平衡。 \ \ endgroup \美元- - - - - -托比Jaffey 6月15日10点16分36分
  • 14
    \ \ begingroup \美元 这是一个糟糕的问题,因为“嵌入式”在决定特定语言及其相关内容是否合适时是一个毫无意义的属性。重点是小系统和大系统,小系统没有运行OS,内存有限,可能不是von-Neuman,可能有各种硬件限制,调用栈,数据栈,你不能动态分配一个Mb甚至一个kb,等等。大多数微控制器都是“小”系统。单板计算机通常是嵌入式的,但通常是“大型”系统。 \ \ endgroup \美元- - - - - -奥林莱斯罗普 12年6月28日11点42分

16个问题16

146
\ \ begingroup \美元

是的,c++在嵌入式系统中仍然有用。正如其他人所说,它仍然依赖于系统本身,就像8位的uC在我的书中可能是一个禁忌,即使有一个编译器在那里,有些人做(颤抖)。使用c++仍然有优势,即使你把它缩小到“c++”之类的东西,即使是在8位的微观世界里。我说的“c++”是什么意思?我的意思是不要使用new/delete,避免异常,避免带有继承的虚类,可能同时避免继承,非常小心使用模板,使用内联函数而不是宏,以及使用常量变量,而不是#定义

我已经在嵌入式系统中使用C和c++工作了十多年,由于一些现实世界的问题动摇了人们的天真,我年轻时对c++的一些热情肯定已经消退了。我在嵌入式系统中见过c++最糟糕的地方,我把它称为“在EE世界中疯狂的CS程序员”。事实上,我正在和我的客户一起改进他们的代码库。

c++的危险在于,它是一个非常非常强大的工具,就像一把双刃剑,如果你在语言和通用编程方面没有受过适当的教育和训练,它就可能把你的胳膊和腿割下来。C更像一把单刃剑,但同样锋利。使用c++很容易获得非常高级的抽象,并创建长期变得毫无意义的模糊接口,这部分是由于c++在使用许多不同的语言特性(模板、OOP、过程化、RTTI、OOP+模板、重载、内联)解决相同问题方面的灵活性。

我完成了两个4小时的c++嵌入式软件研讨会,由c++大师Scott Meyers主持。他指出了一些我以前从未考虑过的关于模板的事情,以及它们对创建安全关键代码的帮助。关键在于,在必须满足严格的安全关键代码要求的软件中,不可能有死代码。模板可以帮助您完成这一点,因为编译器只在实例化模板时创建所需的代码。然而,人们必须更加彻底地学习如何正确地设计这个特性,这在C语言中很难实现,因为链接器并不总是优化死代码。他还演示了模板的一个功能,该功能只能用c++实现,如果NASA实现了一个类似的系统来保护计算中的测量单位,就可以防止火星气候观察者崩溃。

Scott Meyers是一个非常支持模板和内联使用的人,我必须说我仍然对模板的努力持怀疑态度。我倾向于回避它们,尽管他说它们只应该在它们成为最好工具的地方使用。他还指出,c++为您提供了一些工具,可以制作出真正优秀的接口,这些接口易于正确使用,不易错误使用。这也是最难的部分。一个人必须达到精通c++的水平,才能知道如何以最有效的方式应用这些特性,成为最佳的设计解决方案。

OOP也是如此。在嵌入式世界中,您必须熟悉编译器将输出什么样的代码,才能知道您是否能够处理运行时多态的运行时成本。您还需要愿意进行度量,以证明您的设计将满足您的截止日期要求。新的InterruptManager类会使我的中断延迟太长吗?还有其他形式的多态性可能更适合您的问题,如链接时多态性,这是C也可以做的,但c++可以通过Pimpl设计模式(不透明指针)

我这么说是为了说明,c++在嵌入式世界中有自己的位置。你可以恨它,但它不会消失。可以写在一个非常有效的方式,但它是很难学习如何正确地与比C C .有时候工作解决问题,有时表达更好的接口,但是,你必须自学而不是害怕学习。

\ \ endgroup \美元
19
  • 1
    \ \ begingroup \美元 这与我从其他嵌入式系统顾问那里了解到的情况一致。我一直被教导说,使用C语言,你会不断地在小方面割伤自己,但c++中的bug会更少,但当你搞砸了,你就会失去一条腿。谢谢你用一些我没有的专业知识写了一个清晰的答复。 \ \ endgroup \美元- - - - - -Kortuk 6月16日10点14分23分
  • 3.
    \ \ begingroup \美元 在计算机科学专业的记录中,在ee土地上发疯了。在我的工作中,我们的工作代码最糟糕的是由CS专业编写。我们花在努力教他硬件是什么。他使用UML制作了一个结构化系统,并使用正确的继承等基于Java基于Java构建了整个系统。它工作,直到任何更改,然后它是一个糟糕的补丁作业,可以添加功能,或者完全重新设计。代码几乎不可用,因为他有多彻底地困扰着整个继承。 \ \ endgroup \美元- - - - - -Kortuk 6月16日10点14分36分
  • 2
    \ \ begingroup \美元 不仅仅是bug会困扰您,不可维护的代码也会困扰您。当然,当你使用那些整洁的c++特性开始项目时,一切都很顺利,但如果在开发过程中没有认真地进行重构,那么2、3年后,“熵”就会出现。这就是我现在所面临的…在c++中,随着时间的推移,代码腐烂得更快。 \ \ endgroup \美元- - - - - -杰伊·阿特金森 16月16日17:22
  • 3.
    \ \ begingroup \美元 UML和statemachines。你真该查查米罗·萨姆克的东西state-machine.com.他构建了一个高效的系统,易于重构和更改,但确实需要一些时间去了解它。 \ \ endgroup \美元- - - - - -杰伊·阿特金森 16月16日17:24
  • 2
    \ \ begingroup \美元 这实际上取决于您的系统以及您有多少可用内存。你是在内存很少的8位微处理器上写代码吗?那么你最好避免在抽象界面上走极端。如果你正在编写具有大量内存的32位嵌入式系统,那就去做吧。你真的得称一下。例如,每次你将“virtual”世界放在那个类上,你就会得到一个额外的指针,它可能是8位、16位或32位,取决于系统,对于你声明的每个对象实例。你甚至都不会意识到 \ \ endgroup \美元- - - - - -杰伊·阿特金森 11月5日10分,20:47分
63
\ \ begingroup \美元

C ++绝对适用于嵌入式系统。我现在使用良好的开发工具(或缺乏)作为我的主要标准,以便使用特定的微处理器。

在嵌入式系统上使用c++是很好的,因为它们有低的资源成本:

  • 良好使用类/结构带来的模块化
  • 模板如果编译器在有效地编译它们方面做得很好。模板是一个很好的工具,可以重用不同数据类型的算法。

好的方面:

  • 虚函数——我曾经反对这种方法,但资源成本非常低(每个虚函数只占用一个虚函数表),不是每个物体;每个对象一个指向虚函数表的指针;每个虚函数调用一个解引用操作),这样做的最大好处是,它允许你有一个数组,包含几个不同类型的对象,而不需要知道它们是什么类型的。我最近使用这个方法创建了一个对象数组,每个对象代表一个I2C设备,每个对象都有各自的方法。

不要使用的区域,主要是因为运行时开销在小型系统上是不可接受的:

  • 动态内存分配——其他人提到过这个,但这是另一个重要原因使用动态内存分配是因为它代表了时间上的不确定性;使用嵌入式系统的许多原因是为了实时应用程序。
  • RTTI(运行时类型信息)——内存成本相当大
  • 例外,明确的不不,因为执行速度太快了
\ \ endgroup \美元
14
  • \ \ begingroup \美元 谢谢你的建议。很有趣,和我读过的很相似。 \ \ endgroup \美元- - - - - -Kortuk 6月20分10秒,20:38分
  • 1
    \ \ begingroup \美元 实际上,动态内存分配很好,有时是不可避免的。问题在于动态内存回收(以及随后的重用)。RTTI是内存占用者,我同意这一点。但是例外有什么问题呢? \ \ endgroup \美元- - - - - -Wouter van Ooijen 9月6日11点18分
  • 1
    \ \ begingroup \美元 @WoutervanOoijen:例外的问题是,如果喷火调用酒吧在一个试一试/块,酒吧创建一些对象和调用博兹抛出异常时,系统必须以某种方式调用对象的析构函数酒吧在返回控制之前创建喷火.除非完全禁用异常,酒吧将没有办法知道是否博兹可能抛出任何,因此必须包含额外的代码来考虑这种可能性。我希望看到一个带有“受控异常”的c++变体来处理这个问题;如果可以允许异常的例程… \ \ endgroup \美元- - - - - -supercat 12年6月28日16:04
  • 1
    \ \ begingroup \美元 ...必须这样声明,那么编译器只需要在此类例程的调用者中包含异常处理代码。当然,必须添加所有必需的声明(希望避免不必要的声明)可能会有些麻烦,但它将允许在有用的地方使用异常,而不会在不有用的地方增加开销。 \ \ endgroup \美元- - - - - -supercat 12年6月28日16:07
  • 3.
    \ \ begingroup \美元 @WoutervanOoijen:顺便说一下,如果我是设计这类异常处理的ABI的胳膊,我会指定代码调用例程可能退出通过异常应该R14指向一个地址两个字节之前预期的返回地址(这将自然发生如果调用者调用指令后16位字)。被调用的例程将通过添加r15 r14、# 2而不是mov r15、r14;通过异常退出,LDRHS r0,[r14] / add r15,r14,r0.正常退出的循环成本为零,并且没有堆栈框架限制。 \ \ endgroup \美元- - - - - -supercat 12年6月28日16:14
42
\ \ begingroup \美元

是的,c++当然适合于嵌入式系统。首先,让我们澄清一些关于C和c++之间区别的误解:

在嵌入式Micro中,如果您关注的时间或空间限制,您总是需要仔细使用高级语言。例如,许多MCU不良好地处理指针,使用堆栈时非常低效。这意味着使用数组和指针以及递归,必须小心将变量传递给函数。简单的c如:

A [i] = b[j] * c[k];

根据这些变量的性质,可以生成大约4页的说明。

每当你使用任何高级语言,如果你担心时间和空间的限制,你就需要知道怎么做每一个该语言的特性转换为MCU上的机器指令(至少,您使用的每个特性)。这对于C, c++, Ada都是正确的。可能所有语言都包含在小型mcu上无法有效翻译的特性。总是检查反汇编列表,以确保编译器没有为一些琐碎的事情生成大量的指令。

C语言是否适用于嵌入式微处理器?是的,只要你留意生成的代码。
c++适用于嵌入式mcu吗?是的,只要你留意生成的代码。

以下是我认为c++比C更好的原因,即使在8位mcu上:

  • 数据隐藏
  • 更强的打字/检查
  • 使用类的多外围透明性
  • 模板(如果小心使用的话)
  • 初始化列表
  • 常量

这些特性中没有一个比C的典型特性更重。

当你移动到16或32位单片机,然后它开始有意义使用重特性的C(栈、堆、指针、数组、printf等等)。同样的,在一个更强大的单片机就适当使用c++的重特征(栈、堆、引用、STL、新/删除)。

所以,一想到在PIC16上使用c++就不必害怕。如果您正确地了解您的语言和MCU,那么您将知道如何有效地同时使用它们。

25
\ \ begingroup \美元

我总觉得这些辩论读起来很有趣。这并不是关于各种可用语言的优缺点的理性讨论,而是因为你通常可以根据某人的工作/经验/兴趣领域来确定他对这个话题的立场。CS专业人员和维护程序员经常引用Knuth,而那些在现实世界中工作的人则认为他们都疯了(公平地说,我是后者的一员)。

在一天结束的时候,你可以用C或c++或插入语在这里.这取决于开发人员的能力,而不是语言。通常只需要一种语言专家,如果你选择了错误的语言开始,现在需要经解决你的问题,在大多数情况下,这些是唯一的情况下,你需要深入的特性或编译器的技巧来完成这个目标。

我经常听到人们开始这些论点是“我是一个语言专家X和哇啦”老实说,我立即怀疑这些人,因为在我看来,他们已经接近这个问题从错误的角度和在那之后一切都被他们想要使用他们的工具来解决问题和展示“酷”。

我经常看到开发人员首先选择一个工具集,然后试图将其用于解决他们的问题,这是完全错误的,并导致了糟糕的解决方案。

正如我在对另一个答案的评论中提到的,这些语言之争经常演变成争论语言X允许程序员做更多愚蠢的事情。而有趣的阅读,所有这些语句的意思是,你有问题直接雇佣好的开发人员和需要解决的问题,而不是试图创可贴继续雇佣的情况糟糕的开发者和选择这样的工具,他们可以做尽可能少的破坏。

在我看来,优秀的开发者,无论是软件开发还是硬件开发,都会研究问题,构建解决方案,并找到能够让他们以“最佳方式”表达解决方案的工具。如果所需要的工具是你以前从未使用过的,那就不重要了,在你为项目使用了3-4种语言/开发工具之后,选择一个新的工具应该不会对你的开发时间造成太大影响。

当然,“最佳方式”是一个主观的术语,也需要在研究阶段进行定义。我们需要根据手头的问题考虑大量的问题:性能、易于表达、代码密度等。我没有把可维护性包括在这个列表中是有原因的,我不在乎你选择什么语言,如果你选择了合适的工具并花时间去理解问题,这应该是“免费的”。难以维护的代码通常是由于选择了错误的工具或糟糕的系统结构造成的,这将导致代码工作起来非常混乱。

声称任何一种语言都比其他语言“更好”是愚蠢的,没有定义一个特定的感兴趣的问题。面向对象的方法并不总是比函数式方法更好。有一些问题非常适合面向对象设计范式。也有很多人没有。对于许多人们似乎喜欢喋喋不休的语言特性,我们也可以得出同样的结论。

如果您将超过20%的时间花在实际输入代码的问题上,那么您可能正在生成一个非常糟糕的系统,或者拥有非常糟糕的开发人员(或者您仍在学习中)。您应该将大部分时间用于预先绘制问题图,并确定应用程序的各个部分如何交互。坚持一群才华横溢的开发人员在一个房间里标志板和一个问题解决,告诉他们他们不允许编写任何代码或选择任何工具,直到他们感到舒适与整个系统将做更多的工作来改善输出的质量和速度比选择任何热门的新工具开发保证改善开发时间。(查阅scrum development作为与我的观点截然相反的参考)

不幸的现实是,许多企业只能通过编写的代码行数或“有形输出”来衡量开发人员的价值。他们认为在一个房间里用标记板呆3周是效率的损失。开发人员经常被迫加快开发的“思考”阶段,或者由于公司内部的一些政治问题而被迫使用一组工具,“我老板的兄弟在IBM工作,所以我们只能使用他们的工具”,诸如此类的垃圾。或者更糟的是,您从公司得到一组不断变化的需求,因为他们没有能力进行适当的市场研究,或者不了解变化对开发周期的影响。

很抱歉在这个话题上有点跑题,我对这个话题有很强烈的看法。

\ \ endgroup \美元
14
  • 2
    \ \ begingroup \美元 现在,我并不是在某些嵌入式系统的应用程序级别(驱动程序以上)上进行单元测试。单元测试的即时反馈和在开发阶段的早期消除bug是有价值的,但是对于我来说,产生设计的整个TDD范式似乎有点愚蠢。在开始编写代码之前,我更喜欢花些时间“思考”问题,并在头脑中、纸上或白板上把它画出来。我还认为TDD鼓励市场不要对需求做前期研究,因为它应该有助于需求的不断变化。 \ \ endgroup \美元- - - - - -杰伊·阿特金森 6月17日10分1点13分
  • 2
    \ \ begingroup \美元 最后给我的这篇超长的评论做个总结…我们不需要语言专家来设计。我们需要能够使用这种语言的专家设计师。 \ \ endgroup \美元- - - - - -杰伊·阿特金森 6月17日10分1点21分
  • 1
    \ \ begingroup \美元 PRD =产品要求文件,MRD =市场要求文件,TRD =技术要求文件。TDD =测试驱动开发。 \ \ endgroup \美元- - - - - -杰伊·阿特金森 6月17日10分4点34分
  • 1
    \ \ begingroup \美元 @Mark -我同意你关于预先设计的观点,但只是在一定程度上。我认为繁重的前期设计工作是值得的,如果a)你的需求相当稳定/已知,b)做设计的开发者是有经验的.上一页。在工作中,我的任务是做一个设计,这是由我的团队领导安排的时间,我想,“这是多么愚蠢的事情!预先设计可以节省资金(参见《代码完整》一书)??”但在编码过程中,我发现了很多我不知道要找的东西。如果我进行了大量的设计并将代码时间最小化,那么这将是一种浪费。期刊。 \ \ endgroup \美元- - - - - -J. Plfer. 6月17日10点,17点57分
  • 1
    \ \ begingroup \美元 @sheepsimulator我显然同意第二点,我假设主系统架构师是有经验的开发人员。对于第一点,我实际上不同意。我认为,你越是期望需求发生变化,就越需要在设计阶段花费更多的时间,因为你需要生成一个好的、易于更改的设计。我知道一些哲学主张快速发展。在某些情况下,这种方法很有效,就像许多糟糕或缺乏经验的程序员一样。所有这些设计理念归结起来就是在说“我不希望设计一个灵活的系统,所以让我们不要浪费时间去尝试”。 \ \ endgroup \美元- - - - - -马克 6月17日10点19分02分
18
\ \ begingroup \美元

根据我的经验,c++通常不适合小型嵌入式系统。我指的是微控制器和无操作系统的设备。

许多c++ OOP技术依赖于动态内存分配。这在小型系统中经常缺失。

STL和Boost真的展示了C ++的力量,两者都是巨大的占地面积。

c++鼓励程序员将机器抽象出来,因为在受约束的系统中,机器必须被接受。

去年,我将一款商用远程桌面产品移植到了手机上。它是用c++编写的,可以在Windows、Linux和OSX上运行。但是,它严重依赖STL、动态内存和c++异常。为了让它在WinCE、Symbian和无os环境中运行,重写C语言是最明智的选择。

\ \ endgroup \美元
8
  • \ \ begingroup \美元 我同意小系统的说法,但我认为我们对小系统有不同的定义。当你有1kB的ROM,而写得很好的C代码只占用了一个字节的ROM时,这是一个很小的系统。 \ \ endgroup \美元- - - - - -Kortuk 16:20 16:20
  • 7
    \ \ begingroup \美元 我并不是说C不能有更小的占用空间,但是您仍然可以使用c++,并为刚才讨论的内容进行设计,从而获得非常相似的结果。我认为问题是大多数OOP程序员习惯于使用动态内存和非常低效的构造的系统,这导致在低功耗系统中完全无用的代码。 \ \ endgroup \美元- - - - - -Kortuk 6月15日10点16分27分
  • 4
    \ \ begingroup \美元 所以你的意思是你不想用c++,你想用介于C和c++之间的东西(我们就叫它c++吧?)在这种情况下,我同意,有很多人使用c++,只是因为它可用,而不是因为它是最佳的。几乎任何语言都能够生成良好、快速的代码,问题在于如何使用它。大多数关于语言的圣战不是语言能力的结果,而是关于一个白痴做愚蠢的事情有多容易的争论,这确实是一个愚蠢的争论 \ \ endgroup \美元- - - - - -马克 6月16日10日4点
  • 2
    \ \ begingroup \美元 “大多数关于语言的圣战不是语言能力的结果,而是关于一个白痴做愚蠢的事情有多容易的争论,这真的是一个愚蠢的争论。”是一个非常有趣的句子。我需要你的姓,这样我才能引用你的话。 \ \ endgroup \美元- - - - - -Kortuk 6月16日10点14分27分
  • 1
    \ \ begingroup \美元 但我真的不使用C中的动态内存。我必须拥有它。长期我已经读到它可以得到非常非常细分并开始引起问题。我需要非常明确的设计案例,因为内存耗尽,我需要能够确切地监控剩下多少。 \ \ endgroup \美元- - - - - -Kortuk 6月16日10点14分34分
17
\ \ begingroup \美元

任何语言都可以适用于嵌入式系统。嵌入只是意味着:更大设备的一部分,而不是免费使用的计算机。

当被问及一个问题时,这个问题就更相关了实时(困难)有限的资源系统。

对于实时系统来说,c++是最高的语言之一,它仍然适用于在严格的时间限制下编程。除了堆使用(自由操作符)之外,它没有具有不确定执行时间的构造,所以您可以测试您的程序是否满足它的时间要求,如果有更多的经验,您甚至可以预测它。当然,应该避免使用堆,尽管new操作符仍然可以用于一次性分配。c++在C上提供的构造可以很好地用于嵌入式系统:OO、异常、模板。

对于资源非常有限的系统(8位芯片,少于几个Kb的RAM,没有可访问的堆栈),完整的c++可能不适合,尽管它仍可能被用作“更好的C”。

我认为很不幸的是,艾达似乎只被用于某些领域。从很多方面来说,它是一个Pascal++,但却没有与一种从一开始就已经是一团糟的语言向上兼容的负担。(编辑:最糟糕的当然是c。Pascal是一种漂亮但有点不切实际的语言。)

================================================================

编辑:我正在输入一个新问题的答案(“在编写微控制器时,在哪些情况下需要使用c++ ?”)这个是闭合的,所以我将添加我写的内容:

使用的理由从来就没有压倒一切的理由任何编程语言,但在特定情况下,有些参数或多或少有分量。关于这一点的讨论可以在很多地方找到,立场从“永远不要使用c++作为微控制器”到“总是使用c++”。我更倾向于最后一个职位。我可以给出一些论据,但你必须自己决定在特定情况下它们的分量(以及方向)有多大。

  • c++编译器比C编译器更少见;对于一些目标(例如12位和14位核心PICs),根本就没有c++编译器。
  • (好的)c++程序员比(好的)C程序员更少,特别是在那些也(有点)有电子知识的人当中。
  • c++比C有更多不适合小型系统的构造(比如异常、RTTI、频繁使用堆)。
  • C ++具有比C更丰富的(标准)库集,但前一点的后果是C ++库通常使用不适合小型系统的功能,因此不符合小系统。
  • c++比C有更多的结构,可以让你搬起石头砸自己的脚。
  • c++比C有更多的构造允许你这样做防止(是的,在我看来这条和前一条都是正确的)。
  • c++有一组更丰富的抽象机制,因此它支持更好的编程方式,特别是对于库。
  • c++语言的特性(例如构造函数/析构函数、转换函数)使得通过代码查看生成的机器和语言构造的空间和时间成本变得更加困难。
  • c++语言构造使得不太需要知道这些代码是如何被翻译成机器码的,因为它们以一种更抽象的方式做了“正确的事情”。
  • c++语言标准发展迅速,被大型编译器(gcc、clang、microsoft)迅速采用。C语言的发展相当缓慢,很少采用一些较新的特性(变体数组),甚至在后来的标准中已经恢复。这一点特别有趣,因为不同的人用它来支持相反的立场。
  • c++无疑是比C更锐利的工具,你相信你的程序员(或你自己)使用这样的工具来制作一个美丽的雕塑,还是你害怕他们伤害自己,你宁愿接受一个不那么漂亮但风险更低的产品?(我记得我的雕塑老师曾经告诉我,钝的工具在某些情况下可以更多的比尖锐的更危险。)

我的博客有一些关于在小型系统(=微控制器)上使用c++的著作。

\ \ endgroup \美元
    11
    \ \ begingroup \美元

    我希望在裸金属和资源受限系统上添加更多的光线比热量为C ++的讨论。

    c++的问题:

    • 异常尤其是RAM问题,因为所需的“紧急缓冲区”(例如内存溢出异常)可能比可用RAM大,对微控制器来说肯定是一种浪费。有关更多信息,请参见n4049n4234.它们应该被关闭(这是目前未指定的行为,所以要确保永远不要抛出)。第14研究组目前正在研究更好的方法。

    • RTTI可能不值得花费这么多开销,应该关闭它

    • 大型调试构建,尽管这在经典的桌面开发中不是问题,如果调试不适合芯片,它可能是一个问题。问题来自于模板代码或为清晰起见而添加的额外函数调用。这些额外的函数调用将被优化器再次删除,增加的清晰度或灵活性可能是一个巨大的优势,但在调试构建中,这可能是一个问题。

    • 堆分配。尽管STL允许使用自定义分配器,但这对大多数程序员来说可能很复杂。堆分配是非确定性的(即不是硬实时的),尽管在测试中工作过,但碎片可能会导致意外的内存溢出情况发生。堆为了跟踪空闲空间和大小变化而需要的簿记对于小对象来说可能是个问题。通常使用池分配更好(在C和c++中都是如此),但这对于习惯于只使用堆的c++程序员来说是不正常的。

    • 运行时多态性和其他间接调用通常会对性能造成很大的影响,这个问题通常更多是因为优化器无法看穿它们,而不仅仅是实际的抓取和跳转到地址。因此,在C和c++中要避免间接调用,因为在c++中,间接调用在文化中更加根深蒂固(在其他领域也非常有用)。

    • 隐式接口与CLIB可以是有问题的。可能是违反直觉的,即CLIB问题在C ++类别中,但问题出现在并发环境中的隐式共享资源(共享更明确)。使用常见的newlib实现经常拖动在ucs中通常不需要的大量膨胀,另一方面,newlibnanno不重新入口,所以必须序列化(在这里过度简化)访问它。这也是C的问题,但访问更明确。由于拇指的规则,除非您确定它在某种方式(例如,errorno或堆中的Clib中没有访问状态,否则基本上都不从名称空间STD使用。它也很重要,如果您使用线程(我更喜欢RTC)来覆盖新的并删除以同步对Malloc和免费的访问。

    总之,c++有一些问题,但它们基本上都是可以解决的或可以避免的。

    对于C,这里的问题是高阶的。在C语言中,我没有语法上的能力来抽象事物,以便在编译时执行优化或检查不变量。因此,我不能以一种用户不需要知道它们如何工作就能使用它们的方式恰当地封装事物,而且我的大多数错误检测是在运行时完成的(这不仅太晚,而且增加了成本)。本质上,在C中泛型的唯一方法是通过数据,我将一个格式字符串传递给printf或scanf,例如在运行时计算。这是相当困难的编译器证明,我没有使用一些选项,理论上是可能的,当传递正确的数据,这意味着潜在的死代码生成和损失的优化潜力。

    我知道我可能释放shitstorm在这里,但是我的经验在32位微控制器是一个苹果和苹果的比较C和c++写的专家(如c++可能高度模板化)c++更有效的语言只要任何需要通用的(就像在任何库),从本质上说,他们是在非一般情况下是等价的。新手也更容易利用c++中专家库实现者的专业知识。

    同时,一旦输入不是一个int,它实际上就有真正的函数,我无法传递错误的数据,但是某物我碰巧使用了一个int作为一个表示方法,然后有一个潜在的错误(传递一个无效的值或'otherThing'而不是'something')。在C中,我唯一检查用户是否弄错的方法是在运行时。在c++中,我有能力执行一些检查,不是所有的检查,但一些在编译时免费的检查。

    最终,C团队的能力往往与其最弱的程序员不相上下,结果代码的好处要么是多人模式为1,要么是性能损失。我的意思是是高绩效的一个且只有一个独特的工作在一个独特的环境中独特的设计决策或通用足以用于多个环境(其他单片机,其他内存管理策略,其他延迟与吞吐量权衡等等等等),但有一个固有的性能成本。

    在c++中,可以由专家进行封装,并在许多环境中使用,在这些环境中,编译时代码生成可以适应特定的任务,静态检查可以防止用户零成本地做愚蠢的事情。在这里,我们在通用和快速之间的权衡要少得多,因此从成本和收益的角度来看,最终是性能更好、更安全、更高效的语言。

    这是一个有效的批评,仍然有很多好的c++库用于嵌入式,这可能导致务实的决定,主要使用C在c++编译器。在项目中只使用C语言的决定本质上要么是意识形态驱动的,需要遗留支持或承认团队不够自律,避免选择集的愚蠢的事情能做哪一个在C和c++但不是在同一时间足够自律不做任何更大的愚蠢的事情哪一个不能防范在C语言中,但可以在c++中。

    \ \ endgroup \美元
    2
    • \ \ begingroup \美元 这个神秘的c++爱好者会是谁呢?他在个人资料中写道:“显然,这些用户更喜欢保持自己的神秘感。”(顺便说一句,英语很烂)但是,啊哈,地点是“波鸿,德国”.....会议上见! \ \ endgroup \美元- - - - - -Wouter van Ooijen 1月17日18点50分
    • \ \ begingroup \美元 啊,是的,更新了我的个人资料;)很高兴知道你来emBO++,这将是一个很好的人群 \ \ endgroup \美元- - - - - -odinthenerd. 1月17日19点18分
    10
    \ \ begingroup \美元

    我的背景:刚从学校毕业,在贝尔实验室的老程序员手下接受培训;工作3年,2年本科科研项目;VB.NET中的数据采集/过程控制。花了一年半的时间在VB6的企业数据库应用上工作。目前正在为项目工作嵌入式PC 2GB存储,512MB内存,500MHz x86 CPU;几个用c++编写的并发运行的应用程序,中间有一个IPC机制。是的,我年轻。

    我的意见:我认为c++可以有效地工作给定我上面写的环境.诚然,硬实时性能并不是我使用的应用程序的要求,在一些嵌入式应用程序中,这可能是个问题。但以下是我学到的东西:

    • c++与C有本质上的不同(即,没有C/ c++)。虽然所有有效的C都是有效的c++,但c++是一种非常不同的语言,人们需要学习如何用c++编程,而不是C,才能有效地使用它任何的情况。在c++中,您需要面向对象的编程,而不是过程化的编程,也不是两者的混合(包含大量函数的大型类)。通常,您应该专注于创建包含少量函数的小类,并将所有小类组合成一个更大的解决方案。我的一个同事向我解释说,我曾经用程序编写对象,这是一个大混乱,很难维护。当我开始应用更多面向对象的技术时,我发现我的代码的可维护性/可读性提高了。

    • c++以面向对象开发的形式提供了额外的特性简化代码以使其更容易阅读/维护的方法.坦率地说,我不认为OOP在性能/空间效率方面有多大的提高。但我认为OOP是一种可以帮助将一个复杂问题分解成许多小块的技术。这对编写代码的人很有帮助,这是这个过程中不可忽视的元素。

    • 许多反对c++的争论主要与动态内存分配有关。C也有同样的问题。您可以在不使用动态内存的情况下编写面向对象的应用程序,尽管使用对象的好处之一是您可以以一种简单的方式动态地分配这些东西。就像在C中一样,您必须小心如何管理数据以减少内存泄漏,但是RAII技术在c++中简化了这一点(通过将动态内存封装在对象中自动实现析构)。在某些应用程序中,每个内存位置都要计算,这可能太混乱了,难以管理。

    编辑:

    • WRT“Arduino c++”问题我认为没有动态内存管理的c++可以仍然是有用的。你可以将代码组织成对象,然后将这些对象放置到应用程序的不同位置,设置回调接口等。现在我已经在用c++进行开发,我可以看到许多方法,其中一个应用程序使用堆栈上的所有数据仍然可以使用对象。不过我得承认,我从来没有为Arduino写过这样的嵌入式应用程序,所以我没有证据支持我的说法。我有机会在即将到来的项目中做一些Arduino开发——希望我可以在那里测试我的声明。
    \ \ endgroup \美元
    5
    • 2
      \ \ begingroup \美元 我想评论一下你的第二点,你说它有助于将一个复杂的问题分解成许多小块,这个特性应该被忽略。这正是我如此支持c++的原因。大量的编程研究表明,程序规模的线性增长会导致开发时间的指数增长。这与此相反,如果你能够适当地分解一个程序,那么你就可以在开发时间中给出指数衰减。这是目前为止最重要的事情。 \ \ endgroup \美元- - - - - -Kortuk 6月16日10点14分49分
    • \ \ begingroup \美元 关于你的第二点:简单地使用OOP设计方法不会产生更多的分隔代码。拥有一个良好的基础设计,如何表达设计就留给开发人员了。OOP并没有定义正确地分离代码,它提供了另一种选择,更重要的是,提供了这样做的外观,但是,它肯定不会强制执行良好的设计,这取决于开发人员。 \ \ endgroup \美元- - - - - -马克 6月17日10点,2点58分
    • \ \ begingroup \美元 这总是正确的。我从来没有听说过一种语言能够执行好的设计。我想我们主要是在暗示,这是开发人员的工作,c++使它易于使用和以一种有组织的方式实现。 \ \ endgroup \美元- - - - - -Kortuk 6月17日10分4点43分
    • \ \ begingroup \美元 @Mark -我同意。这对我来说是一个学习的过程。 \ \ endgroup \美元- - - - - -J. Plfer. 6月17日10点13分
    • \ \ begingroup \美元 “在c++中,你需要面向对象的编程,而不是程序化的编程”——为什么?您可以使用类似于C的过程性c++,并从您喜欢的c++特性中进行选择。例如:Const,引用,枚举类,命名空间,…你会错过完整的c++的优点,但仍然比使用普通的C更好。 \ \ endgroup \美元- - - - - -Wouter van Ooijen 1月14日20点24分
    7
    \ \ begingroup \美元

    是的,c++的问题是增加了代码的内存占用。

    在一些系统中,你要计算字节,在这种情况下,你将不得不接受运行的成本接近你的系统的边界,增加C的开发成本。

    但是,即使是在C语言中,对于一个设计良好的系统,也需要将所有东西都封装起来。设计良好的系统是困难的,c++为程序员提供了一个非常结构化和可控的开发方法。学习OOP是有成本的,如果你想改用它,你就会接受它,而且在许多情况下,管理层宁愿继续使用C而不付出成本,因为很难衡量提高生产力的转换的结果。你可以看到一篇文章我是嵌入式系统专家Jack Ganssle

    动态内存管理是魔鬼。不完全是,问题在于自动路径,动态内存管理在PC上工作得很好,但你至少可以期待每隔几周重启一台PC。您会发现,随着嵌入式系统持续运行5年,动态内存管理可能会变得一团糟,实际上开始出现故障。甘塞尔在他的文章中讨论了像堆栈和堆这样的东西。

    有些事情在c++中,更容易导致问题和使用很多资源,消除动态内存管理和模板是大步骤来保持c++的足迹接近的足迹C。这仍然是c++,您不需要动态内存管理或c++模板写好。我没有意识到他们删除了异常,我认为异常是我在发行版中删除的代码的重要部分,但直到那时才使用。在字段测试中,我可以让异常生成消息,通知我捕获了异常。

    \ \ endgroup \美元
    2
    • 1
      \ \ begingroup \美元 我过去同意代码占用是一个问题,但最近似乎闪存大小对微控制器的价格影响很小,比RAM大小或IO引脚的数量要小得多。 \ \ endgroup \美元- - - - - -Wouter van Ooijen 9月6日13:21
    • \ \ begingroup \美元 在我看来,关于动态记忆的争论更为重要。我见过工业系统可以连续运行数周,但诊断层(用c++编写)将重新启动的时间限制在12小时左右。 \ \ endgroup \美元- - - - - -德米特里•Grigoryev 6月3日15日12:57
    6
    \ \ begingroup \美元

    我认为这个anti-C + +咆哮莱纳斯·托瓦尔兹的作品很有趣。

    c++最糟糕的特性之一就是它让很多东西都依赖于上下文——这意味着当你查看代码时,本地视图很少提供足够的上下文来了解发生了什么。

    他说的不是嵌入式系统世界,而是Linux内核开发。对我来说,相关性来自于:c++需要理解更大的上下文,我可以学习使用一组对象模板,当我必须在几个月后更新代码时,我不相信自己会记住它们。

    (另一方面,我目前正在使用Python(不是c++,而是使用相同的OOP范例)开发一个嵌入式设备,它将会有这个问题。在我看来,这是一个强大的嵌入式系统,10年前就可以被称为PC了。)

    6
    \ \ begingroup \美元

    我认为其他答案都很好地说明了利弊和决策因素,所以我想总结一下并添加一些评论。

    对于小型微控制器(8位)来说,这是不可能的。你只是在伤害自己,没有收获,你会放弃太多的资源。

    对于高端微控制器(例如32位,10或100 MB的RAM和存储空间),有一个像样的操作系统,这是完全可以的,我敢说,甚至推荐。

    所以问题是,界限在哪里?

    我不确定,但一旦我开发了一个系统,16位的uC与1 MB RAM和1 MB存储在c++,只是事后后悔。是的,它是有效的,但是我所做的额外工作不值得。我必须使它适合,确保像异常这样的事情不会产生泄漏(OS+RTL支持是相当有缺陷和不可靠的)。此外,OO应用程序通常会进行许多小的分配,而这些分配的堆开销是另一个噩梦。

    基于这方面的经验,我假设在未来的项目中,我将只在至少16位的系统中选择c++,并且至少有16mb的RAM和存储空间。这是一个任意的限制,可能会根据应用程序的类型、编码风格和习惯用法等而有所不同。但考虑到警告,我建议采用类似的方法。

    \ \ endgroup \美元
    5
    • 3.
      \ \ begingroup \美元 我不同意这个观点,c++不是因为系统资源而突然变得可以接受的,好的设计实践可以让c++的足迹保持在C的足迹所在。这导致OOP设计的代码占用了相同的空间。写得很差——C也可以很差。 \ \ endgroup \美元- - - - - -Kortuk 1月12日11日15:35
    • 1
      \ \ begingroup \美元 这取决于您的应用程序有多大,以及您使用了多少需要更多空间的某些特性(如模板和异常)。但就我个人而言,我宁愿使用C,也不愿将自己限制在受限的c++中。但即便如此,你还是会有更大的RTL、虚方法、构造函数/析构函数链调用的开销……这些影响可以通过仔细的编码来减轻,但是这样你就失去了使用c++的主要原因、抽象和高层次的视角。 \ \ endgroup \美元- - - - - -fceconel 11年1月12日18:12
    • \ \ begingroup \美元 “但即使这样,你也会有一个更大的RTL的开销”——无稽之谈,当我使用c++时,我得到的RTL与C相同:本质上是0。 \ \ endgroup \美元- - - - - -Wouter van Ooijen 1月14日20日18:19
    • \ \ begingroup \美元 “虚拟方法谢谢”-不知道这些是什么,但你肯定不会得到它们除非你使用虚函数,在这种情况下,等价的C程序应该有函数指针。 \ \ endgroup \美元- - - - - -Wouter van Ooijen 1月14日18:20
    • \ \ begingroup \美元 “我宁愿使用C而不愿把自己限制在一个受限的c++中”——我不能为你说话,但当在一个小微控制器上使用C语言时,我使用重新训练的C语言,例如:没有堆,没有浮点数,没有setjmp/jongjmp。同样,我使用了受限的c++。 \ \ endgroup \美元- - - - - -Wouter van Ooijen 1月14日18:20
    4
    \ \ begingroup \美元

    c++的一些特性在嵌入式系统中是有用的。还有一些例外情况,可能会很昂贵,而且其成本可能并不总是显而易见。

    如果让我选择的话,会有一种流行的语言,它结合了两种语言的优点,并包含了两种语言所缺乏的一些特性;一些供应商包括一些这样的特性,但是没有标准。我希望看到以下几点:

    1. 异常处理有点像Java,可以抛出或泄漏异常的函数必须这样声明。虽然从编程的角度来看,这种声明的要求可能有点烦人,但它可以提高代码的清晰度,因为函数可能在成功时返回任意整数,但也可能失败。许多平台可以在代码中以低成本处理这个问题,例如在寄存器中有返回值,在进位标志中有成功/失败指示。
    2. 仅重载静态和内联函数;我的理解是,C的标准主体避免了函数重载,以避免名称混乱。只允许重载静态函数和内联函数可以避免这个问题,并且可以提供重载外部函数的99.9%的好处(因为.h文件可以用不同命名的外部函数来定义内联重载)
    3. 为任意或特定的可编译时解析的常量参数值重载。有些函数在传递常量值时内联效率很高,但传递变量时内联效率很低。其他时候,如果值是常量,那么代码可能是优化,如果不是常量,则可能是悲观。例如:
      Inline void copy_uint32s(uint32_t *dest, const uint32_t *src, __is_const int n) {if (n <= 0) return;else if (n = = 1) {dest [0] = src[0];}其他如果(n = = 2) {dest [0] = src [0];桌子[1]= src [1];} else if (n = = 3) {dest [0] = src [0];桌子[1]= src [1];桌子[2]= src [2];} else if (n = = 4) {dest [0] = src [0];桌子[1]= src [1];桌子[2]= src [2];/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
      如果'n'可以在编译时计算,上面的代码将比调用memcpy更有效,但如果'n'不能在编译时计算,生成的代码将比简单调用memcpy的代码更大更慢。

    我知道c++之父不太喜欢c++的嵌入式版本,但我认为它可以提供一些相当大的改进,而不仅仅是使用C。

    有谁知道是否有任何类型的标准在考虑上面的东西?

    \ \ endgroup \美元
    8
    • \ \ begingroup \美元 en.wikipedia.org/wiki/Embedded_C%2B%2B \ \ endgroup \美元- - - - - -托比Jaffey 5月13日15点54分
    • \ \ begingroup \美元 @Joby Taffey:我想我编辑了我的帖子,忽略了提到c++的创造者不喜欢嵌入式子集;我知道他们做了很多努力,但据我所知,他们并没有取得那么大的进展。我确实认为,标准化语言将会有明确的用途,它将适应8位处理器,我上面描述的功能似乎在任何平台上都是有用的。你听说过有哪一种语言能提供上述第三种语言吗?这似乎很有用,但我从未见过任何语言提供这一功能。 \ \ endgroup \美元- - - - - -supercat 11年5月13日16:05
    • \ \ begingroup \美元 “c++之父”没有任何嵌入式系统编程经验,为什么有人会关心他的观点呢? \ \ endgroup \美元- - - - - - 6月4日15分6点38分
    • \ \ begingroup \美元 事实上,一些有影响力的人似乎确实关心他在各种问题上的观点,这似乎是其他人这么做的原因,就其本身而言。我在想,既然我写了上面的内容,模板的日益强大的功能可能已经增加了基于在编译时可以解析的常量的重载的新可能性,尽管远不如作为编译时特性支持的那样干净(据我所知,我们可以指定一个模板,它应该按顺序尝试各种各样的东西,并使用第一个不会失败的…… \ \ endgroup \美元- - - - - -supercat 6月4日15日13:33分
    • \ \ begingroup \美元 ...但这将要求编译器浪费相当多的精力来编译可能的替换,而这些替换最终将被丢弃。能够更清楚地说:“如果这是一个常量,那么就这么做;否则,在“没有任何错误的开始”的情况下这样做似乎是一种更干净的方法。 \ \ endgroup \美元- - - - - -supercat 6月4日15日13:34
    3.
    \ \ begingroup \美元

    c++不仅仅是一种编程语言:

    a)这是一个“更好的”c b)它是一个面向对象的语言c)它是一种允许我们编写泛型程序的语言

    尽管所有这些功能都可以单独使用,但当三者同时使用时,效果最好。尽管如此,如果您只选择其中之一,嵌入式软件的质量将会提高。

    a)这是一个“更好”的c

    c++是一种强类型语言;您的程序将从这个特性中受益。

    有些人害怕指示。c++包含了引用。重载的函数。

    值得一提的是:这些特性都不会出现在更大或更慢的程序中。

    它是一种面向对象的语言

    有人在这篇文章中说,把机器抽象到微控制器中不是一个好主意。错了!我们所有人,嵌入式工程师,总是抽象机器,只是用其他的sintax,而不是c++。我看到的这个论点的问题是,一些程序员不习惯用对象来思考,这就是为什么他们看不到OOP的好处。

    当你准备使用微控制器的外设时,很可能外设已经以设备驱动程序的形式为我们(从你自己或第三方那里)抽象出来了。正如我之前所说,该驱动程序使用C sintax,正如下一个示例所示(直接取自NXP LPC1114示例):

    /*在TICKRATE_HZ设置匹配和中断定时器*/

    Chip_TIMER_Reset (LPC_TIMER32_0);

    Chip_TIMER_MatchEnableInt (LPC_TIMER32_0, 1);

    chip_timer_setmatch(lpc_timer32_0,1,(timerfreq / tickrate_hz2));

    Chip_TIMER_ResetOnMatchEnable (LPC_TIMER32_0, 1);

    Chip_TIMER_Enable (LPC_TIMER32_0);

    你看到抽象了吗?因此,当出于同样的目的使用c++时,通过c++的抽象和封装机制,将抽象提升到下一个层次,成本为零!

    它是一种允许我们编写泛型程序的语言

    泛型程序是通过模板实现的,模板对我们的程序来说也没有成本。

    此外,静态多态是通过模板实现的。

    虚拟方法,RTTI和例外。

    当使用虚拟方法时,有一个折衷:更好的软件vs一些性能上的损失。但是,请记住,动态绑定很可能是使用虚表(函数指针数组)实现的。我已经在C中做过很多次了(甚至是在常规的基础上),所以我没有看到使用虚方法的缺点。而且,c++中的虚方法更加优雅。

    最后,关于RTTI和异常的建议:不要在嵌入式系统中使用它们。不惜一切代价避免它们!!

    2
    \ \ begingroup \美元

    我的背景,嵌入式(mcu, pc, unix,其他),实时。安全至关重要。我把以前的雇主介绍给了STL。我不再那样做了。

    一些火焰内容

    c++适合于嵌入式系统吗?

    咩。编写c++是一件痛苦的事,维护c++也是一件痛苦的事。c++是可以的(不要使用一些特性)

    c++在微控制器?操作系统?烤面包机吗?嵌入式电脑?

    我再说一遍meh。C +不是太糟糕,但ADA不那么痛苦(这真的说了什么)。如果你喜欢我的幸运,你可以做嵌入的java。检查数组访问,没有指针算术使得非常可靠的代码。嵌入式Java中的垃圾收集器不是最高优先级,并且存在范围内存和对象重用,因此设计精心设计的代码可以在没有GC的情况下运行。

    面向对象编程在微控制器上有用吗?

    肯定是。UART是一个对象.....DMAC是一个对象…

    物体状态机非常容易。

    c++是否将程序员从硬件中移除得太远而无法提高效率?

    除非它是PDP-11,否则C不是你的CPU。c++最初是基于C的预处理器,所以Bjarne Stroustrup在AT&T的时候不会因为慢Simula模拟而被嘲笑。c++不是你的CPU。

    去找一个运行java字节码的MCU。用Java程序。嘲笑C组的人。

    Arduino的c++(没有动态内存管理,模板,异常)应该被认为是“真正的c++”吗?

    不。就像所有的MCU的C编译器一样。

    嵌入式Java或嵌入式ADA是标准化的(ish);其他一切都是悲哀。

    \ \ endgroup \美元
    5
    • 2
      \ \ begingroup \美元 找到支持Java的微控制器有那么容易吗?我认为这将大大限制选择。关于性能损失,你有什么经验(因为在uCs中你通常不会有JIT)?实时系统中GC不可预测性的影响是什么? \ \ endgroup \美元- - - - - -fceconel 1月12日1月1日14:39
    • 2
      \ \ begingroup \美元 有哪些mcu支持嵌入式Java? \ \ endgroup \美元- - - - - -J. Plfer. 11年1月12日17:36
    • \ \ begingroup \美元 www.ajile.com首先。 \ \ endgroup \美元- - - - - -蒂姆Williscroft 11年1月13日9点41分
    • \ \ begingroup \美元 Ada + 1。它在嵌入式方面有很多优势,包括Arduinos。 \ \ endgroup \美元- - - - - -user_1818839 12月15日12点14分
    • \ \ begingroup \美元 micros的可移植java VM是开源的。dmitry.co / index . php ? p = / 04.的想法/… \ \ endgroup \美元- - - - - -蒂姆Williscroft 12月15日12日23:28
    -2
    \ \ begingroup \美元

    <咆哮>

    首先,我认为c++是一门蹩脚的语言。如果你想使用OOP,写Java程序。c++没有执行OOP范例,因为直接内存访问完全在你的能力范围内。

    如果你有一个MCU,你谈论的很可能是少于100kB的闪存。你想在一种语言中编程,它的内存抽象是:当我声明一个变量或数组时,它得到内存,句号;malloc(在c++中又名“new”关键字)应该或多或少地禁止在嵌入式软件中使用,除非在程序启动过程中偶尔调用。

    地狱,在嵌入式编程中有(频繁)时间,其中C不是足够低的,并且您需要做像分配变量的事情,以便写入内联组件以拧紧您的中断服务例程(ISR)。关键词如“挥发性”变得漂亮的达不为了解。你花了很多时间操纵内存水平,而不是对象的水平。

    你为什么要欺骗自己,认为事情比实际情况要简单?

    < /咆哮>

    -2
    \ \ begingroup \美元

    嵌入式系统是为了完成某些特定的任务而设计的,而不是为了完成多个任务而设计的通用计算机。嵌入式系统是计算机硬件和软件的结合。C是所有现代语言之母。它是一个低级但强大的语言和处理所有类型的硬件。因此,C/ c++是开发嵌入式系统软件的最佳选择,它对每一个嵌入式系统都是非常有用的。操作系统UNIX是用C编写的。因为成功的软件开发经常是为给定的项目选择最好的语言,所以令人惊讶的是,C/ c++语言已经证明自己适用于8位和64位处理器;在内存为字节、千字节和兆字节的系统中。C语言具有处理器独立性的优点,它允许程序员专注于算法和应用程序,而不是专注于特定处理器体系结构的细节。然而,这些优势中的许多同样适用于其他高级语言。但是C/ c++在许多其他语言失败的地方成功了吗?

    \ \ endgroup \美元
    1
    • 6
      \ \ begingroup \美元 我真的不确定这对讨论有什么影响。 \ \ endgroup \美元- - - - - -戴夫花呢 12年10月19日22:10

    不是你想要的答案?浏览其他带标签的问题问你自己的问题