面向对象对嵌入式系统不利吗?为什么?

发布于 2024-09-10 11:53:51 字数 1431 浏览 4 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

剑心龙吟 2024-09-17 11:53:51

虽然我不确定它是否回答了你的问题,但我可以总结一下我以前的公司源代码是纯 C 的原因。

首先值得总结一下情况:

  • 我们想要编写大量的“核心”代码,这些代码可以在不同平台之间高度移植。大量 ARM 嵌入式系统(主要是中档手机;智能手机和运行不同时期 RTOS 的手机)
  • 平台通常都有一个可用的 C 编译器,尽管有些不支持浮点“double”。
  • 在某些情况下,平台对标准库有合理的实现,但在许多情况下却没有。
  • 大多数平台上都没有 C++ 编译器,并且在提供 C++ 标准库、STL 或异常的支持的地方,情况也存在很大差异。
  • 调试器通常不可用(可以将调试 printfs 发送到的串行端口被认为是一种奢侈)
  • 我们总是可以访问合理数量的内存,但通常无法访问合理的 malloc() 实现

鉴于此,我们完全使用 C 语言工作,即使如此,也只有一组有限的 C 89。生成的代码具有高度可移植性。不过,我们经常使用面向对象的概念。

如今,“嵌入式”是一个非常广泛的定义。它涵盖了从没有 RAM 或 C 编译器的 8 位微处理器到本质上高端 PC(尽管不运行 Microsoft Windows)的所有内容 - 我不知道您的项目/公司在这个范围内的位置。

Whilst I'm not sure it answers your question, I can summarise the reasons my previous companies source code was pure C.

It's firstly worth summarising the situation:

  • we wanted to write a large amount of "core" code that would be highly portable across a large number of ARM embedded systems (mostly mid-range mobile phones; both smart phones and ones running RTOSs of various ages)
  • the platforms generally had a workable C compiler, though some for example didn't support floating point "double"s.
  • in some cases the platform had a reasonable implementation of the standard library, but in many cases it didn't.
  • a C++ compiler was not available on most platforms, and where it was available support for the C++ standard library, STL or exceptions was highly variable.
  • debuggers often weren't available (a serial port you could send debug printfs to was considered a luxury)
  • we always had access to a reasonable amount of memory, but often not to a reasonable malloc() implementation

Given that, we worked entirely in C, and even then only a restricted set of C 89. The resulting code was highly portable. We often used object orientated concepts though.

These days "embedded" is a very wide definition. It covers everything from 8 bit microprocessors with no RAM or C compilers upto what are essentially high end PCs (albeit not running Microsoft Windows) - I don't know where your project/company sits in that range.

吃兔兔 2024-09-17 11:53:51

从表面上看,动态内存分配是与面向对象软件设计完全不同的概念,所以它完全是错误的。您可以采用面向对象的设计,而不使用动态内存分配。

事实上,你可以在一定程度上用 C 语言进行面向对象(这就是 Linux 内核所做的)。许多嵌入式开发人员不喜欢 C++ 的真正原因是它非常复杂,并且很难用它编写直接且可预测的代码。 Linus 最近有一篇不错的咆哮< /a> 为什么他不喜欢 C++(它比他的旧的更好、更合理,我承诺)。可能大多数人都没有很好地表达它。

Taking your quote at face value, dynamic memory allocation is completely separate concept from object-oriented software design, so it's outright false. You can have object-oriented design, and not use dynamic memory allocation.

In fact, you can do OO in C to an extent (that's what Linux kernel does). The real reason that many embedded developers don't like C++ is that it's very complex and it is hard to write straight-forward and predictable code in it. Linus has a good recent rant on why he does not like C++ (it's better and more reasoned than his old one, I promise). Probably most folks just don't articulate it very well.

自演自醉 2024-09-17 11:53:51

是什么让你说 C++ 是面向对象的? C++ 是多范式的,由于其开销,并非 C++ 提供的所有功能都对嵌入式市场有用。 (所以......只是不要使用这些功能!问题解决了!)

What makes you say that C++ is Object Oriented? C++ is multiparadigm, and not all of the features that C++ provides are useful for the embedded market due to their overheads. (So... Just don't use those features! Problem solved!)

平生欢 2024-09-17 11:53:51

面向对象非常适合嵌入式系统。它非常关注封装、数据隐藏和代码共享。人们可以拥有无​​需划分或动态内存分配的面向对象嵌入式系统。

无论是面向对象、面向数据还是过程编程,划分和动态内存分配都是嵌入式系统的敌人。这些概念可能会也可能不会用于面向对象设计的实现。

面向对象允许 UART 类在不知道消息对象内容的情况下传输消息对象的实例。消息可以是基类并具有多个后代类。

C++ 语言通过允许构造函数、复制构造函数和析构函数来帮助促进嵌入式系统中的安全编码,这些函数只有在最严格的 C 语言嵌入式系统中才会被记住。

使用 C 语言进行异常处理也是一件痛苦的事情。 C++ 提供了更好的嵌入到该语言中的设施。

C++ 语言提供了用于编写通用代码来处理不同数据类型的模板。一个典型的例子是环形缓冲区或循环队列。在 C 语言中,必须使用“指向 void 的指针”,以便可以传递任何对象。 C++ 提供了一个模板,这样人们就可以编写一个 Circular_Queue 类,它可以处理不同的数据类型,并具有更好的编译时类型检查。

继承可以实现更好的代码共享。共享代码被分解到基类中,并且可以创建共享相同功能的子类;通过继承。

C语言提供函数指针。 C++ 语言为函数对象(带有属性的函数指针)提供了便利。

抱歉,我只是不喜欢那些因为谣言以及对 C++ 的了解和经验很少而将嵌入式系统限制为 C 语言的人。

Object Oriented is great for embedded systems. It focuses a lot on encapsulation, data hiding, and code sharing. One can have Object Oriented embedded systems without division or dynamic memory allocation.

Division and dynamic memory allocation are enemies of embedded systems regardless of Object Oriented, Data Oriented or procedural programming. These concepts may or may not be used in the implementation of Object Oriented designs.

Object Oriented allows for a UART class to transmit instances of Message objects without knowing the content of the Message objects. A Message could be the base class and have several descendant classes.

The C++ language helps promote safe coding in embedded systems by allowing constructors, copy constructors, and destructors, which would only remembered in the highest disciplined C language embedded systems.

Exception handling is also a pain to get working in the C language. The C++ provides better facilities embedded into the language.

The C++ language provides templates for writing common code to handle different data types. A classic example is a ring buffer or circular queue. In the C language, one would have to use "pointers to void" so that any object could be passed. C++ offers a template so one can write a Circular_Queue class that works with different data types and has better compile-time type checking.

Inheritance allows for better code sharing. The shared code is factored into a base class and child classes can be created that share the same functionality; through inheritance.

The C language profides function pointers. The C++ languages provides facilities for function objects (function pointers with attributes).

Sorry, I just don't like those people who limit embedded systems to C language because of rumors and little knowledge and experience with C++.

葬﹪忆之殇 2024-09-17 11:53:51

面向对象设计本身并不坏。答案就在你的引述中。特别是在实时嵌入式系统中,您希望使代码尽可能轻量和高效。您引用中提到的内容(对象、除法、动态内存分配)相对重量级,通常可以用更简单的替代方案替换(例如,使用位操作来近似除法、在堆栈上分配内存或使用静态池)以改进时间关键型系统中的性能。

Object-oriented design by itself isn't bad. The answer lies in your quote. Especially in real-time embedded systems, you want to make your code as light and efficient as possible. The things mentioned in your quote (objects, division, dynamic memory allocation) are relatively heavyweight and can usually be replaced with simpler alternatives (for eg. using bit-manipulation to approximate division, allocating memory on the stack or with static pools) to improve performance in time-critical systems.

调妓 2024-09-17 11:53:51

“面向对象”对于嵌入式系统来说并不是什么坏事。 OO 只是一种思考软件的方式。

对于嵌入式系统来说,不好的地方是,一般来说,它们的调试器不太复杂,可以这么说,C++“在你背后”做了很多疯狂的事情。那些难以访问的代码会让你发疯。

Nothing about 'object-oriented' is bad for embedded systems. OO is just a way of thinking about software.

What's bad for embedded systems is that, in general, they have less sophisticated debuggers, and C++ does a lot of crazy stuff 'behind your back', so to speak. Those pieces of hard-to-get-access-to code will drive you nuts.

权谋诡计 2024-09-17 11:53:51

C++ 的设计理念是不要为不使用的东西付费。因此,除了缺乏良好的嵌入式编译器之外,没有真正的原因。

也许 CFront 可以将 C++ 编译为 C,它有无数的编译器...

编辑:Comeau 编译器将 C++ 转换为纯 C,因此无编译器参数不会撑不住了

C++ was designed with the philosophy of don't pay for what you don't use. So apart from the lack of good embedded compilers, there's no real reason.

Maybe CFront could have compiled C++ into C, which has a myriad of compilers...

Edit: The Comeau compiler transforms C++ into plain C, so the no-compiler argument doesn't hold.

追风人 2024-09-17 11:53:51

正如其他人所指出的,“嵌入式”包含广泛且多样的硬件/软件选项。但是...

您给出的报价将使微控制器嵌入式类型颤抖。动态分配是一个禁忌,如果出现错误,系统就会以不可预测的方式崩溃。强烈建议不要使用除法,因为它们会占用执行时间永远。对象之所以不被鼓励,是因为它们往往携带大量“东西”,所有这些“东西”都会占用空间,而微控制器没有任何空间。

我认为嵌入式是小型且具体的项目,您不必太担心可扩展性或可移植性。您可以用 C 语言编写干净的代码,该代码仅可靠地执行您希望设备执行的操作。您选择一个芯片系列,这样您就可以在不同的硬件选项之间移动(几乎)相同的代码,并对您编写的端口进行细微调整或配置熔丝的初始化。

因此,您不需要定义

  1. 4 轮运输车
  2. 丰田

因为您只在丰田汽车上工作。凯美瑞和卡罗拉之间的加速度差异作为常数存储在寄存器中。

As others have noted, 'embedded' encompasses a broad and varied range of hardware/software options. But...

The quote you give will give microcontroller embedded types shivers. Dynamic allocation is a no-no, if you have an error, you crash the system in unpredictable ways. Divides are heavily discouraged since they take forever in execution time. Objects are only discouraged insofar as they tend to carry lot's of 'stuff' around with them, all that 'stuff' takes up space, and microcontrollers don't have any.

I think of embedded as being projects that are small and specific, you don't worry much about extensibility or portability. You write clean code in C that does only and exactly what you want your device to do, reliably. You choose one chip family so you can move your (almost the) same code among different hardware options with minor tweaks to the port your writing too or initialization of configuration fuses.

So, you don't need to define

  1. 4 wheeled Transportation
  2. Car
  3. Toyota

Since you're only working on Toyotas. And the difference in accelerations between a Camry and Corolla are stored as constants in a register.

带刺的爱情 2024-09-17 11:53:51

如上所述,面向对象/malloc/数学在你背后所做的事情会带来惩罚——无论是代码大小还是CPU周期,这在嵌入式中通常是短缺的。

举个例子,在循环中包含 sqrt() 函数会在递归计算中增加太多开销,因此我们必须将其删除并对其进行快速近似,如果我没记错的话,请使用查找表。

无论如何,使用您喜欢的任何工具/语言,但您至少需要能够揭开盖子并检查在您背后生成了多少额外代码。

As said above, it's what object-oriented / malloc / math do behind your back that carries a penalty - both in code size and CPU cycles which are usually in short supply in embedded.

As an example, including the sqrt() function in a loop added so much overhead in recursive calculations that we had to remove it and work a fast approximation around it, using a lookup table if I remember correctly.

By all means use any tools/langauges you like, but you need to at least be able to lift the lid and check just how much extra code is being generated behind your back.

我要还你自由 2024-09-17 11:53:51

编程始终是使用正确的工具来完成工作。没有固定的答案,在嵌入式世界中尤其如此。如果您想熟练掌握嵌入式开发,您将像熟悉 C++ 一样熟悉 C。

Programming is always about using the right tool for the job. There are no pat answers, and that is especially true in the embedded world. If you want to become skilled in embedded development you will be just as intimately familier with C as you are with C++.

呆° 2024-09-17 11:53:51

首先,我们来区分一下:

因此,我们希望人们不要使用divide ...、malloc ...或其他会带来巨大损失的面向对象实践。

除法和 malloc 并不是面向对象编程所独有的,它们也存在于过程语言中(并且大概是函数式的,以及您可能想到的任何其他范例)。

如果系统的资源足够有限,那么除法和 malloc 在嵌入式系统上可能会成为问题,这是事实,但无论您使用哪种编程范例,它们都将成为问题。


主要问题是“面向对象对嵌入式系统有害吗?”。

首先,“面向对象”的范围相当广泛。有些人对于它的实际含义有不同的看法。有一个极简主义的定义,其中对象本质上只是一组函数(或“方法”)和数据,还有一个更“纯粹”的定义,还包括继承和多态性等功能。

如果您采用 OOP 的极简定义,那么不会 - OOP 对于嵌入式系统来说并不坏。它确实取决于语言,但使用对象完全有可能与不使用对象一样便宜(在某些情况下可能更便宜)。在 C++ 中,一个对象(没有虚拟方法,我稍后会介绍)占用的内存不会比它的各个字段(如果它们不是对象的一部分)占用的内存多。在 C++ 中,对象(的大小)等于其各部分(的大小)之和。

然而,如果您采用 OOP 的“清教徒”观点并坚持包含继承和多态性,那么答案是“是的,这很糟糕”。继承也许不太重要(取决于语言),但通过虚拟方法实现的多态性确实是一个内存消耗者。虚拟函数通常通过维护一个“vtable”(虚拟方法表)来实现,该表存储指向正确函数的指针,并且每个对象必须存储一个指向其 vtable 的指针以启用动态分派(调用虚函数)才能正常工作。在某些情况下,继承可以比不需要继承的解决方案使用更多的内存 - 通常在将继承与组合进行比较时,组合有时会使用更少的内存。

最后一点,特别是对于 C++ 的情况(因为这通常是人们谈论在嵌入式系统上使用 OOP 时的意思)。人们经常说“C++ 在你背后做了奇怪的事情”——它确实做了一些事情,但在查看代码时这些事情并不是立即显而易见的,例如生成我之前提到的 vtable,但是它不会“在背后做这些事情”。你的背部”试图阻止你,它做这些事情是因为它们只是需要实现正在使用的功能。总的来说,“幕后”发生的有害事情很少,而且它所做的事情并不完全神秘或神秘,它们通常是众所周知的,并且是程序员在编程时应该注意的事情。嵌入式系统。如果您不了解它们,那么您就没有正确了解您的工具,您应该对它们进行更多研究。

话虽如此,请记住,人们可以自由选择使用和不使用哪些语言功能。避免使用虚拟函数等更昂贵的功能是绝对有意义的,但仅仅因为它有一些昂贵的完全可选功能(例如虚拟函数)而放弃整个语言(例如 C++)是没有意义的。函数)——这简直就是把婴儿和洗澡水一起倒掉了。

First, let's pick this apart:

so we prefer people not to use divide ..., malloc ..., or other object oriented practice that carry large penalty.

Division and malloc are not unique to object oriented programming, they are present in procedural languages too (and presumably functional, and whatever other paradigms you might think of).

Division and malloc can be a problem on an embedded system if the system has sufficiently limited resources, that much is true, but they will be a problem no matter what programming paradigm you use.


Onto the main issue "Is object orientation bad for embedded systems?".

Firstly, 'object orientation' is quite a broad spectrum. Some people have conflicting ideas about what it actually means. There's a minimalist definition where an object is essentially just a bundle of functions (or 'methods') and data, and there's a more 'purist' definition that also includes features like inheritance and polymorphism.

If you take the minimalist definition of OOP then no - OOP is not bad for embedded systems. It does depend on the language, but it's entirely possible for using objects to be just as cheap as not using objects (and possibly cheaper in some situations). In C++, an object (without virtual methods, which I'll get to in a moment) takes up no more memory than its individual fields would if they weren't part of an object. In C++, (the size of) an object is equal to the sum of (the size of) its parts.

However, if you take the 'puritan' view of OOP and insist on including inheritance and polymorphism then the answer is 'yes, it is bad'. Inheritance is perhaps less of a concern (depending on the language), but polymorphism via virtual methods is a definite memory chewer. virtual functions are usually implemented by maintaining a 'vtable' (a virtual method table) that stores pointers to the correct functions, and each object must store a pointer to its vtable to enable dynamic dispatch (the process of calling virtual functions) to work properly. There are circumstances in which inheritance can use more memory than solutions that don't require inheritance - typically when comparing inheritance to composition, composition sometimes uses less memory.

One last point, particularly for the case of C++ (since that's usually what people mean when they talk about using OOP on embedded systems). People often say that "C++ does strange things behind your back" - it does do some things without those things being immediately obvious when looking at the code, such as producing the vtables I mentioned earlier, however it doesn't do these things "behind your back" in an attempt to thwart you, it does these things because they are simply needed to implement the features being used. Overall there are very few detrimental things that happen 'behind the scenes', and the things it does aren't exactly arcane or mysterious, they're generally quite well known and they're things the programmer ought to be aware of when programming for an embedded system. If you don't know about them then you don't know your tools properly and you should research them some more.

Having said all that, remember that people are free to be selective with which language features they do and don't use. It makes absolute sense to avoid the more expensive features like virtual functions, but it doesn't make sense to forgo an entire language (like C++) simply because it has a few expensive entirely optional features (like virtual functions) - that's just throwing the baby out with the bathwater.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文