简体   繁体   English

嵌入式 C++:是否使用异常?

[英]Embedded C++ : to use exceptions or not?

I realize this may be subjective, so will ask a concrete question, but first, background:我意识到这可能是主观的,所以会问一个具体的问题,但首先是背景:

I have always been an embedded software engineer, but usually at Layer 3 or 2 of the OSI stack.我一直是嵌入式软件工程师,但通常在 OSI 堆栈的第 3 层或第 2 层。 I am not really a hardware guy.我不是一个真正的硬件人。 I have generally always done telecoms products, usually hand/cell-phones, which generally means something like an ARM 7 processor.我通常总是做电信产品,通常是手机/手机,这通常意味着像 ARM 7 处理器。

Now I find myself in a more generic embedded world, in a small start-up, where I might move to "not so powerful" processors (there's the subjective bit) - I cannot predict which.现在我发现自己处于一个更通用的嵌入式世界,在一家小型初创公司中,我可能会转向“不那么强大”的处理器(这是主观的一点)——我无法预测是哪个。

I have read quite a bit about debate about exception handling in C++ in embedded systems and there is no clear cut answer.我已经阅读了很多关于嵌入式系统中 C++ 中异常处理的辩论,但没有明确的答案。 There are some small worries about portability and a few about run-time, but it mostly seems to come down to code size (or am i reading the wrong debates?).有一些关于可移植性和一些关于运行时的小担忧,但它似乎主要归结为代码大小(或者我读错了辩论?)。

Now I have to make the decision whether to use or forego exception handling - for the whole company, for ever (it's going into some very core s/w).现在我必须决定是使用还是放弃异常处理——对于整个公司来说,永远(它会进入一些非常核心的软件)。

That may sound like "how long is a piece of string", but someone might reply "if your piece of string is an 8051, then don't. If, OTOH, it is...".这可能听起来像“一段字符串有多长”,但有人可能会回答“如果你的一段字符串是 8051,那么不要。如果,OTOH,它是......”。

Which way do I jump?我往哪个方向跳? Super-safe & lose a good feature, or exceptional code and maybe run into problems later?超级安全并失去了一个好的功能,或者特殊的代码,以后可能会遇到问题?

In terms of performance, my understanding is that exceptions actually reduce the size and increase the performance of the normal execution paths of code, but make the exceptional/error paths more expensive. 在性能方面,我的理解是异常实际上减小了代码的正常执行路径的大小并提高了性能,但使异常/错误路径更加昂贵。 (often a lot more expensive). (常贵了不少 )。

So if your only concern is performance, I would say don't worry about later. 因此,如果你唯一担心的是表现,我会说以后不用担心。 If today's CPU can handle it, then tomorrows will as well. 如果今天的CPU可以处理它,那么明天也会如此。

However . 但是 In my opinion, exceptions are one of those features that require programmers to be smarter all of the time than programmers can be reasonably be expected to be. 在我看来,例外是那些需要程序员更聪明的是不是程序员可以合理预期的是时间的特点之一。 So I say - if you can stay away from exception based code. 所以我说 - 如果你可以远离基于异常的代码。 Stay away. 远离。

Have a look at Raymond Chen's Cleaner, more elegant, and harder to recognize . 看看Raymond Chen的Cleaner,更优雅,更难以识别 He says it better than I could. 他说这比我做得好。

The most problem with exceptions -- they don't have predictable time of execution. 异常中最大的问题 - 它们没有可预测的执行时间。 Thus they are not suitable for hard real-time applications (and I guess most embedded application doesn't fall in this category). 因此它们不适合硬实时应用程序(我想大多数嵌入式应用程序都不属于这一类)。

The second is (possible) increasing of binary's size. 第二个是(可能)增加二进制的大小。

I would propose you reading of Technical Report on C++ Performance which specifically addresses topics that you are interested in: using C++ in embedded (including hard real-time systems) and how exception-handling usually implemented and which overhead it has. 我建议你阅读有关C ++性能技术报告,它专门针对您感兴趣的主题:在嵌入式(包括硬实时系统)中使用C ++,以及如何实现异常处理以及它具有哪些开销。

The choice of whether to use exceptions or not should really lie with whether they are going to fit your program's problem domain well or not. 是否使用例外的选择应该取决于它们是否能够很好地适应您的程序的问题域。

I've used C++ exceptions extensively, both in retrofitting into old C code, and in some newer code. 我已经广泛使用了C ++异常,无论是在改造旧的C代码还是在一些较新的代码中。 (HINT: Don't try to re-fit 20 year old C code that was written in a low memory environment with all manner of inconsistent exceptions. It's just a nightmare). (提示:不要试图重新安装在低内存环境中编写的具有各种不一致异常的20岁C代码。这只是一场噩梦)。

If your problem is one that lends itself to handling all the errors in one spot (say, a TCP/IP server of some sort, where every error condition is met with 'break down the connection and try again'), then exceptions are good - you can just throw an exception anywhere and you know where and how it will be handled. 如果您的问题适合处理一个地方的所有错误(例如,某种类型的TCP / IP服务器,其中每个错误条件都满足'分解连接并再试一次'),那么异常就是好的 - 您可以在任何地方抛出异常,并且知道它将在何处以及如何处理。

If, on the other hand, your problem doesn't lend itself to central error handling, then exceptions are a ROYAL pain, because trying to figure out where something is (or should be) handled can easily become a Sisyphean task. 另一方面,如果你的问题不适合中央错误处理,那么例外是一种皇家的痛苦,因为试图弄清楚某些东西(或者应该)被处理的东西很容易成为一种Sisyphean任务。 And it's really hard to see the problem just by looking at the code. 通过查看代码很难看到问题。 You instead have to look at the call trees for a given function and see where that function's exceptions are going to end up, in order to figure out if you have a problem. 相反,您必须查看给定函数的调用树,并查看该函数的异常将在何处结束,以便确定您是否有问题。

I'd say use exceptions appropriately if the runtime environment supports them. 如果运行时环境支持异常,我会说适当使用异常。 Exceptions to handle extraordinary conditions are fine, and can cause little overhead depending on the implementation. 处理特殊情况的例外情况很好,并且根据实现情况可能会产生很少的开销。 Some environments don't support them, especially in the embedded world. 某些环境不支持它们,尤其是在嵌入式环境中。 If you ban them, be careful to explain why. 如果禁止它们,请小心解释原因。 I once had a guy that, when told not to use exceptions, did a divide by zero instead. 我曾经有过一个人,当被告知不要使用例外情况时,他会做一个零除。 Not exactly what we had in mind. 不完全是我们想到的。

I think the problem is that many people voice their opinion without having a solid understanding of how exception handling in C++ works.我认为问题在于,许多人表达了他们的意见,却没有充分理解 C++ 中的异常处理是如何工作的。

I have recently started at a new company, and there is consensus that we should not use exceptions, because we can't test them, because nondeterministic behaviour, etc etc. All wrong, of course.我最近在一家新公司开始工作,大家一致认为我们不应该使用异常,因为我们无法测试它们,因为不确定的行为等等。当然,全错了。

When we talk about the overhead of having exception handling used in the code, we need to carefully consider overhead on top of what?当我们谈论在代码中使用异常处理的开销时,我们需要仔细考虑开销在什么之上? Granted it comes at a cost, but that is the cost of alternative?当然,这是有代价的,但那是替代的成本吗? Say we are using return error codes.假设我们正在使用返回错误代码。 In such scenario HALF of the if() statements in the source code will be dedicated to testing error codes and forwarding them up the call stack.在这种情况下,源代码中的 if() 语句的一半将专门用于测试错误代码并将它们转发到调用堆栈。 Not making this up, actual metric of the codebase I'm looking at.我正在查看的代码库的实际指标不是编造的。 And most of it is to deal with a) events that can't pretty much ever happen, like not having memory at the start of an embedded application and b) events that if they actually happen, we can not do anything about anyway, other than shutdown.其中大部分是处理 a) 几乎不可能发生的事件,例如在嵌入式应用程序开始时没有 memory 和 b) 如果它们真的发生了,我们无论如何也无能为力,其他比关机。

In this case introduction of exception handling would significantly reduce complexity of the code, separating handling of rare events from the business as usual logic.在这种情况下,引入异常处理将显着降低代码的复杂性,将罕见事件的处理与常规业务逻辑分开。 And saves ton's of overhead, because the error code checking is happening all the time.并节省了大量的开销,因为错误代码检查一直在进行。 Further, it significantly reduces the size of the code.此外,它显着减少了代码的大小。 Think how much effort is needed to propagate error codes up the stack through 10 different functions, until we get somewhere where we can officially bail.想想需要多少努力才能通过 10 个不同的函数在堆栈中传播错误代码,直到我们到达可以正式保释的地方。 Using the exception handling you can bypass the 10 intermediary levels of functions, and go straight to where we can deal with it.使用异常处理,您可以绕过 10 个中间级别的函数,并将 go 直接转到我们可以处理的地方。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM