Re: [Boston.pm] Exceptions as control flow
Steve Scaffidi wrote: Bob Rogers wrote: Better is a language design where the handler runs in the dynamic context of the exception, and gets to decide what to do, and how much information to capture. Like Perl 6. (Does this mean we're back on topic now? ;-) It's certainly a powerful option to have. Java, for example, does allow an exception class to take such actions within its constructor and can choose not to trace the stack. It can't cancel itself -- you need to use an extra method call layer of abstraction to get that effect. But that flexibility obviously comes with complexity. If people find it hard to trace the flow of control in the presence of exceptions, it can't be any easier when exceptions might or might not jump anywhere. ___ Boston-pm mailing list Boston-pm@mail.pm.org http://mail.pm.org/mailman/listinfo/boston-pm
Re: [Boston.pm] Exceptions as control flow
Interesting post and thread. I'm always learning something new on this list. My experience has been in authentication code. If login is broken, everything is broken. Hence, there are high uptime requirements. But it is only money, not lives at stake. Also, not embedded in a shipping device, but running on a general purpose computer. So, yeah, we had a stack. C++/Java are OK. Both here and in network device code, I have seen patterns that eschew dynamic allocation, preferring fixed object pools. When you run out, you start dropping connections (which is actually more graceful than degrading everyone's performance), or something similar to keep reliable service. Point being, there is a gradation of programming techniques appropriate to different environments. However, I have yet to find an actual working environment that would call for using Exceptions as normal flow control (same goes for setjmp/longjmp). In my experience, if you find yourself reaching for heroic of coding techniques, you need to rethink and regroup and come at the problem a different way. That's how you get the 10x factors of speed improvement. Let hardware upgrades give you the 10-20% improvements. At 01:46 PM 3/18/2010 -0500, Greg London wrote: So anyone have a guess at which tools they mean? The compiler itself or testing and verification tools? When you are working on a life-critical avionics (LCA) project, everything must be certified to the same stringent requirements. That means the compiler must be certified as strictly as the software being compiled. Same goes for hardware. you can't just use any old processor off the shelf for LCA. I don't know, but I would guess that embedded coding standards may be liberalizing (for lack of a better word) in response to hardware changes. Actual CPUs, with hardware support for a stack are the norm these day, no? Don't only very high volume, low cost mass market products (e.g. remote controls) still use PIC controllers? Likewise, compilers have a _lot_ more miles on them by now, so trust levels should be improved there as well. Ime, stack based programming is actually much simpler for us poor human programmers to understand. I think that results in better, more reliable running programs. Even the awful old languages (COBOL, FORTRAN) have had proper stack support for 30 years now. Perhaps the embedded world has joined the party. ___ Boston-pm mailing list Boston-pm@mail.pm.org http://mail.pm.org/mailman/listinfo/boston-pm
Re: [Boston.pm] Exceptions as control flow
On Fri, Mar 19, 2010 at 10:49:43AM -0500, Charlie Reitzel wrote: Likewise, compilers have a _lot_ more miles on them by now, so trust levels should be improved there as well. I don't know about that. Hopefully the compiler writers that embedded programmers use are doing a better job than these guys: http://connect.microsoft.com/VisualStudio/feedback/details/336316/missing-destructor-calls-when-optimization-is-enabled#details -- Mike Small sma...@panix.com ___ Boston-pm mailing list Boston-pm@mail.pm.org http://mail.pm.org/mailman/listinfo/boston-pm
Re: [Boston.pm] Exceptions as control flow
Greg London Wrote: [ John Redford wrote:] you have a call stack, and you want code to execute quickly in order to meet a time constraint (hard or not), Now, checking every next() call to see if it returns EOF (or sets some EOF flag variable) is inefficient, You're not thinking like an embedded controller engineer. You're trying to make your best case run faster. ...I think something has been lost here. You seem to be implying that writing fast code does not matter for embedded code, because it runs against a fixed clock. But that sounds wrong to me. I think of examples like graphics display hardware. There are hard clock points in the process of going from ASCII to text on screen or vectors to rendered 3d graphics; but that does not mean that the code does not benefit from being fast -- it permits higher resolutions, fancier graphics processing, and other dimensions of work to be accomplished within that clock period. I am saying that using exceptions as non-local-goto is one technique that can make stuff fast. Sometimes makes sense; sometimes not; not a cure-all. And fast is important in some code (but not all code or even most code). More precisely, I am saying that the opposing (yet very popular) position -- exceptions should only represent unrecoverable error conditions and should be very rare and should be implemented inefficiently -- is wrong. An embedded guy has to get their code to run at some frame rate. Say 30 hz. His code has to run one frame of data every 33 milliseconds. and then the processor goes to sleep until the timer wakes it up for the next frame. What does it mean if you're code is more efficient but still runs at 30 hz? It means you can do more. Higher res, higher sampling, more complex algorithms, etc. No? You're talking about the problem like someone used to programming for desktops. Make things run as fast as possible and slow things down as needed to get done. For example, you'd never read a file of unknown length in avionics or any kind of embedded controller application like an engine controller. At least not on a per-frame basis. You might dedicate so many clock cycles per frame to read some fixed number of bytes per frame, but you wouldn't have code that says read until EOF and then code it with an exception so that you respond to EOF more efficiently. I did say it was a classic example, not a claim about embedded controllers. The point it is there to make is that one can avoid testing branching (with all the CPU-design-specific performance benefits (or not) that may entail). You're trying to make your best case better, and you worst case is how ever long it takes till you read EOF. Embedded controller guys have to make their worst case meet some minimum. And no open-ended processes are allowed per frame. But Nothing about throwing exceptions is open-ended. It simply pops the stack starts to execute some other code. It's just a code path. One could argue that such code paths are problematic to trace when overused; but one could probably say the same about simple 'if' statements being used. If you have 40 'if's in a function that depends on finishing in less time than it would take to execute the heavy side of every branch, then you still have a difficult static analysis problem. In some cases, exceptions could simply such problems; in others they'd make them harder -- again, not a cure-all. ___ Boston-pm mailing list Boston-pm@mail.pm.org http://mail.pm.org/mailman/listinfo/boston-pm
Re: [Boston.pm] Exceptions as control flow
I don't know, but I would guess that embedded coding standards may be liberalizing (for lack of a better word) in response to hardware changes. Actual CPUs, with hardware support for a stack are the norm these day, no? Don't only very high volume, low cost mass market products (e.g. remote controls) still use PIC controllers? Well, there's embedded as in runs windows mobile and then there's embedded as in must acheive a frame rate of 30 hz. Hardware improvements cannot guarantee frame rate if the system architecture cannot guarantee every step is a fixed operation. i.e. any system that will stop and read a file of undefined length until EOF is reached is the first kind of embedded, a small desktop. if you're working on the must achieve a frame rate of 30 hz kind of device, then you're system architecture is going to be fundamentally different than desktop applications. It's an entirely different mindset. ___ Boston-pm mailing list Boston-pm@mail.pm.org http://mail.pm.org/mailman/listinfo/boston-pm
Re: [Boston.pm] Exceptions as control flow
On Thu, Mar 18, 2010 at 11:40:40AM -0400, Martin Cracauer wrote: FWIW, in C++ as of today's gcc, a function exiting with a thrown exception is roughly 1000 times more expensive than a regular call/return ... More expensive defined how? Memory usage? CPU cycles? Developer effort? I just had to kill some instances in my employer's codebase that were using thrown exceptions as regular flow control. Yeah, well, that's dumb. Exceptions are for *exceptional* circumstances. -- David Cantrell | Bourgeois reactionary pig You can't spell AWESOME without ME! ___ Boston-pm mailing list Boston-pm@mail.pm.org http://mail.pm.org/mailman/listinfo/boston-pm
Re: [Boston.pm] Exceptions as control flow
Charlie Reitzel wrote: Point being, there is a gradation of programming techniques appropriate to different environments. However, I have yet to find an actual working environment that would call for using Exceptions as normal flow control (same goes for setjmp/longjmp). In my experience, if you find yourself reaching for heroic of coding techniques, you need to rethink and regroup and come at the problem a different way. That's how you get the 10x factors of speed improvement. Let hardware upgrades give you the 10-20% improvements. I am not sure if you're saying that heroic coding techniques should always be seen as a sign that you're doing something wrong. I could not agree with that, though I could agree (who would not) with the notion that most of the time most code benefits more from re-thinking the problem than from concentrating on heroic optimization. However, I am reminded of Charles Petzold's excellent article in 'Beautiful Code' in which he explains the rationale behind the implementation of BitBlt, which could surely be considered in the realm of heroic techniques, as it uses dynamic machine code generation to avoid test/branch cases. He then proceeds to describe a modern variation that dynamically generates .NET IL code (which then dynamically turns into machine code) to handle image processing tasks. (Much of the article is visible in Google books.) No one would say that all code would be better if it worked this way. But there are times places for such techniques, just as there are times places for Perl, Python, C, D, Forth, APL, F#, JavaScript, Lua, etc, etc, etc... ___ Boston-pm mailing list Boston-pm@mail.pm.org http://mail.pm.org/mailman/listinfo/boston-pm
Re: [Boston.pm] Exceptions as control flow
David Cantrell wrote on Fri, Mar 19, 2010 at 04:04:33PM +: On Thu, Mar 18, 2010 at 11:40:40AM -0400, Martin Cracauer wrote: FWIW, in C++ as of today's gcc, a function exiting with a thrown exception is roughly 1000 times more expensive than a regular call/return ... More expensive defined how? Memory usage? CPU cycles? Developer effort? CPU cyles. [...] 28.1 nsec/call: 'rand' 25.3 nsec/call: 'random' 7401.7 nsec/call: 'cpp_testhrow_throw' 15.9 nsec/call: 'cpp_testhrow_no_throw' 13.7 nsec/call: 'cpp_testhrow_no_possible_throw' 7.7 nsec/call: 'cpp_testhrow_no_cleanup_no_throw' 3.5 nsec/call: 'cpp_testhrow_no_cleanup_no_possible_throw' [...] That has one object with a minimal destructor in the cleanup. K8 2.4 GHz, gcc-4.3 Code at: http://www.cons.org/cracauer/general-tester.cc Martin -- %%% Martin Cracauer craca...@cons.org http://www.cons.org/cracauer/ FreeBSD - where you want to go, today. http://www.freebsd.org/ ___ Boston-pm mailing list Boston-pm@mail.pm.org http://mail.pm.org/mailman/listinfo/boston-pm
Re: [Boston.pm] Exceptions as control flow
...I think something has been lost here. You seem to be implying that writing fast code does not matter for embedded code, because it runs against a fixed clock. The thing being lost is the difference between code that you think is fast and code that you have *proven* is fast. the FAA requires that life critical avionics be *proven* to be fast *and* accurate, *no matter what*. And while desktop code jockeys will throw a few test cases at their code (top down testing) and decide that it is fast enough, the FAA won't let that approach fly. Proving a system is fast and accurate no matter what inputs it sees isn't easy. If you can prove the low level blocks behave a certain way no matter what input they get, and if you can prove that putting those blocks together doesn't create any new behaviour, then you have essentially proven your system. If your blocks behave a certain way in standalone, but start behaving differently depending on how the rest of the system is behaving, then you really haven't proven anything. Most FAA requirements prohibit stuff that causes the system to behave differently depending on how the rest of the system is behaving. Malloc being a good example. You can't prove that malloc will always work no matter what because you don't know what your system might do with malloc. Even if you get malloc to work perfectly, how do you *prove* that the system won't try to allocate more memory than exists? You can't. What you're doing is you're telling me that you think using exceptions will be faster than using other control structures. And maybe you can provide a case where the real objective measures show that it is faster. But you haven't *proven* it will be fast and accurate *no matter what*. ___ Boston-pm mailing list Boston-pm@mail.pm.org http://mail.pm.org/mailman/listinfo/boston-pm
Re: [Boston.pm] Exceptions as control flow
GL and then there's GL embedded as in must achieve a frame rate of 30 hz. Where 30 Hz is a variable, and must may be of varying strength / harm - * otherwise the screen refresh will be skipped jerky, or only partial ugly; ... * otherwise Flight Law control loop time is violated and positive control of the airframe is no longer guaranteed expensive Yes. longjmp was once not only less C code but far far quicker to unwind a deep stack than the standard return(-1) if rc 0; # lather rinse repeat in old C on old slow hardware without optimized stack instructions. The return()'s register swizzling is far cheaper on today's hardware which has support for such, so that is less true today. Doing an exception throw in OO C++ or Java or even Perl requires MUCH MORE *implicit* work as the exception propagates through the call stack checking at each frame for potential catches and potential destructors for on-stack objects being freed. An actual longjmp in C++ would cause any off-stack resources held by over-jumped stack to leak. Exceptions are perhaps the least pernicious form of COME FROM flow control, but that is damning with faint praise. COME FROM are as a class generally even more evil than the GO TO. However, TRY{THROW}CATCH{} exceptions (including eval{die} and even longjmp ) are less egregious action-at-a-distance COME FROM than their older siblings the SIGNAL handlers like $SIG{FPE} and PL/I ON CONDITIONs. At least die or THOW provides a syntactic marker at the spot that the COME FROM might come from, whereas any arithmetic expression is a possible raiser of $SIG{FPE}, and any opcode may be hit by an external $SIG{KILL} or $SIG{INT}. And the CATCH is conveniently at the point of last call, not buried somewhere in boilerplate like $SIG{KILL}= \sub {state $zombie; $zombie++}; Such action at a distance is best used only as the emergency escape hatch they were designed for. SIG is lean, as it needs to be at Interrupt level, and it can throw a die, which can be as expensive as it needs to be to free resources as it winds up the stack, since it is only called exceptionally. If one actually needs non-emergency action-at-a-distance (not common, usually a refactoring is what is needed, possibly into a process pipeline), Co-Routine callyield is often an appropriate, controlled, and efficient mechanism [Eg http://search.cpan.org/~mlehmann/Coro-5.21/Coro/Intro.pod ] A good reason for such is when a parse-transform-generate pipeline needs to be optimized as thread-to-thread in-memory pass instead of slower IPC, eg when doing a Jackson Program Design inversion of a parser to create the generator. (although XSLT or XProc may be better than bespoke implementation of a complex XML2XML transform, someone has to build the XSLT XProc engines, and sometimes source or target doc isn't in the *ML family ... .) Another example is http://search.cpan.org/dist/Perl6-GatherTake/ (EXPERIMENTAL!) which uses Coro to implement Perl6's gather-take keywords to build lazy list generators. And PLACK/PSGI use Coro http://deps.cpantesters.org/depended-on-by.pl?dist=Coro-5.21 Bill @ $DayJob Not an official statement of anyone ___ Boston-pm mailing list Boston-pm@mail.pm.org http://mail.pm.org/mailman/listinfo/boston-pm
Re: [Boston.pm] Exceptions as control flow
Greg London wrote: And no open-ended processes are allowed per frame. But Nothing about throwing exceptions is open-ended. How deep is your stack? That does not really matter. What matters is the complexity of the flow. I suspect I know what you're thinking here, based on what you say below; but it's not the only possible scenario, and it's not what I am trying to advocate as a reasonable use of exceptions, or even exceptions-as-goto. For example, consider code with a single exception handler which sits at the top of the program (first stack frame). Any exception, anywhere will jump to this code and run it. That's pretty simple. It may pop 3 frames or 300. Dosen't really matter; The complexity of the flow is, fundamentally, almost no different than if the throw was rewritten to be a call to a function that does whatever the handler does -- the key difference being that the stack pointer is adjusted so that you can return to the top-level in one hop, instead of having to return -1 and test that 3 or 300 times, at each level doing another return -1 to pop one more stack frame off. That's the win. But it does not have to be complex or difficult to analyze. It could be. But it does not have to be. It simply pops the stack starts to execute some other code. at least in life critical avionics, the verification process is bottom up. You verify the low level blocks do what they're supposed to do, and then you integrate the blocks. Integration does not change the behaviour of teh blocks, so integration does not require that you verify that you created new behaviours. How do you verify a low level block that does a throw? It will behave differently depending on who is doing the catch. You have put the cart before the horse here. Or perhaps the airplane before the tug. The verification process you describe is premised on the idea that exceptions are outlawed; and thus it would be hard to verify code with exceptions using that process. Ok. Fine. No one is saying you need to use exceptions. No one is saying that airplanes and life critical avionics need to use exceptions. Heck, I am generally saying that there is a time place for everything. And that time is not always and that place is not everywhere. But, if exceptions were not outlawed, perhaps a different verification process would be able to analyze appropriate use of them effectively. It's not a campaign to change avionics. It's not even a campaign to advocate using Perl for avionics. If anything, you're making my general (marketing) point -- Perl isn't best for everything. [...] Not necessarily. At which point, the desktop application programmer will say something along the lines of But I know what I'm doing. And the FAA guy will say I can't prove that. But do all programming techniques need to be approved by the FAA? ___ Boston-pm mailing list Boston-pm@mail.pm.org http://mail.pm.org/mailman/listinfo/boston-pm
Re: [Boston.pm] Exceptions as control flow
But do all programming techniques need to be approved by the FAA? Any used in licensed devices subject to FAA or FDA or NSA/DoD or NASA review, ranging from the Space Shuttle flight computer to on insulin pump. Testing doesn't count with them. That puts *Engineering* into Software Engineering. Bill Been there, done that, in a prior life ___ Boston-pm mailing list Boston-pm@mail.pm.org http://mail.pm.org/mailman/listinfo/boston-pm
Re: [Boston.pm] Exceptions as control flow
Greg London wrote: What you're doing is you're telling me that you think using exceptions will be faster than using other control structures. And maybe you can provide a case where the real objective measures show that it is faster. But you haven't *proven* it will be fast and accurate *no matter what*. WHOA! I _am_ telling you I think exceptions are faster than other control structures _In_ _Some_ _Cases_. But you can just think about that. Or not. I'm happy to explain clarify if I am unclear. But I am not here to tell you what to do and prove why you should do it. Do whatever you want. Use whatever makes sense for you. After all, that's exactly why other people don't use Perl. ___ Boston-pm mailing list Boston-pm@mail.pm.org http://mail.pm.org/mailman/listinfo/boston-pm
Re: [Boston.pm] Exceptions as control flow
I _am_ telling you I think exceptions are faster than other control structures _In_ _Some_ _Cases_. I'm happy to explain clarify if I am unclear. I'm curious. Maybe I'm out of my depth, pun not intended, but I was under the impression that thrown exceptions have to unwind the stack anyway. Is there some way exceptions are usually implemented that doesn't cost as much as unwinding the stack one level at a time? It seems like 3-or-300 does matter, in that you have to check for and possibly call some number of destructors or risk leaking all over the place. This is a fantastic discussion and I'm happy to see it here. ~Conor ___ Boston-pm mailing list Boston-pm@mail.pm.org http://mail.pm.org/mailman/listinfo/boston-pm
Re: [Boston.pm] Exceptions as control flow
WHOA! I _am_ telling you I think exceptions are faster than other control structures _In_ _Some_ _Cases_. But you can just think about that. Or not. I'm happy to explain clarify if I am unclear. But I am not here to tell you what to do and prove why you should do it. It went like this: Mark asked: But for safety critical projects, the no rtti, no exceptions rule is pretty common isn't it? Not sure if it's justified or not, but very common from what I hear. Something to do with code verification, provability? Not that that gives any lessons for application code in other domains, necessarily. I explained why no exceptions in FAA life critical code. You then respond with: Well, you get one exception at a time, much like you get one if or goto or return at a time. No different than jumps. at which point saying exceptions are No different than jumps is sort of a red flag. You then go on in that same email to use the example of using exceptions to read a file until EOF. Which wouldn't be allowed in FAA code. Whether exceptiosn are faster than normal constructs in any particular case could be objectively measured. But the original question was why no exceptions in cases like flight code and so on. And in that case it's not just about being fast, its about about being provably fast no matter what. Greg ___ Boston-pm mailing list Boston-pm@mail.pm.org http://mail.pm.org/mailman/listinfo/boston-pm
Re: [Boston.pm] Exceptions as control flow
William Ricker wrote: Yes. longjmp was once not only less C code but far far quicker to unwind a deep stack than the standard return(-1) if rc 0; # lather rinse repeat in old C on old slow hardware without optimized stack instructions. The return()'s register swizzling is far cheaper on today's hardware which has support for such, so that is less true today. Doing an exception throw in OO C++ or Java or even Perl requires MUCH MORE *implicit* work as the exception propagates through the call stack checking at each frame for potential catches and potential destructors for on-stack objects being freed. As there are somewhat optimized implementations of return, there are optimized implementations of exceptions which do not require stack-walking in order to find the handler code frame. It is possible to maintain a separate handler stack, for example -- numerous other approaches are possible, depending on the language constraints. The details vary. CPU support varies. Languages vary. What people are comfortable using varies. Perhaps a little code will say something: foo () { a = openFile(A); if ( FAIL = a ) return FAIL; ...use a... b = openFile(B); if ( FAIL = b ) { close(a); return FAIL; } ...use a b... b = openFile(B); if ( FAIL = c ) { close(a); close(b); return FAIL; } ...use a b c... ...And so on... close(c); close(b); close(a); } bar () { try { a = openFile(A); ...use a... b = openFile(B); ...use a b... b = openFile(B); ...use a b c... ...And so on... } finally { close(c); close(b); close(a); } } baz () { a = openFile(A); if ( FAIL = a ) goto a; ...use a... b = openFile(B); if ( FAIL = b ) goto b; ...use a b... b = openFile(B); if ( FAIL = c ) goto c; ...use a b c... ...And so on... c: close(c); b: close(b); a: close(a); return FAIL; } As the saying goes: there's more than one way. Suit yourself. ___ Boston-pm mailing list Boston-pm@mail.pm.org http://mail.pm.org/mailman/listinfo/boston-pm
Re: [Boston.pm] Exceptions as control flow
On Fri, Mar 19, 2010 at 11:07 AM, Conor Walsh c...@adverb.ly wrote: I _am_ telling you I think exceptions are faster than other control structures _In_ _Some_ _Cases_. I'm happy to explain clarify if I am unclear. I'm curious. Maybe I'm out of my depth, pun not intended, but I was under the impression that thrown exceptions have to unwind the stack anyway. Is there some way exceptions are usually implemented that doesn't cost as much as unwinding the stack one level at a time? It seems like 3-or-300 does matter, in that you have to check for and possibly call some number of destructors or risk leaking all over the place. The issue is this. If you don't use exceptions then you have to have if checks on every return for exceptional conditions. Those checks are individually fast, but there are a lot of them. If there are a great number of needed checks per exceptional condition, then it is faster overall to remove those checks and throw an exception when needed. Even though it is slower when you throw that exceptions. In a desktop environment this makes sense. However in some other contexts, such as real time embedded programming, it likely doesn't. And the issue there is the difference between average running time and worst case running time. You can see the same issue with, for example, using a hash as a data structure. Average access time for a hash is O(1). Worst case is O(n). In many environments hashes make sense. But if you're looking to guarantee that you finish in a particular time slice, hashes are a simply terrible data structure. This is a fantastic discussion and I'm happy to see it here. It is surprisingly involved and detailed. I've been happy to read through it. Ben ___ Boston-pm mailing list Boston-pm@mail.pm.org http://mail.pm.org/mailman/listinfo/boston-pm
Re: [Boston.pm] Exceptions as control flow
Conor Walsh writes: Maybe I'm out of my depth, pun not intended, but I was under the impression that thrown exceptions have to unwind the stack anyway. Is there some way exceptions are usually implemented that doesn't cost as much as unwinding the stack one level at a time? It seems like 3-or-300 does matter, in that you have to check for and possibly call some number of destructors or risk leaking all over the place. Also (relative to Ben Tilly's mail), it is possible to use techniques like maintaining a table of current handlers and using dynamic jumps in order to bypass uninteresting stack frames and hop directly to the finally code that calls destructors such, and to the handler for the exception being raised. Of course, if a given implementation presumes Exceptions are always errors, it may walk the stack anyway and build up a whole data structure that describes where the exception took place. That would indeed be fairly slow to say the least. But they don't have to be like that. Even still, as Ben said, a slow exception mechanism can nonetheless be faster than the overhead of a number of test/branch cases. ___ Boston-pm mailing list Boston-pm@mail.pm.org http://mail.pm.org/mailman/listinfo/boston-pm
Re: [Boston.pm] Exceptions as control flow
In a desktop environment this makes sense. However in some other contexts, such as real time embedded programming, it likely doesn't. And the issue there is the difference between average running time and worst case running time. I'd kiss you right now if I could... ;) ___ Boston-pm mailing list Boston-pm@mail.pm.org http://mail.pm.org/mailman/listinfo/boston-pm
Re: [Boston.pm] Exceptions as control flow
On Fri, Mar 19, 2010 at 2:31 PM, Greg London em...@greglondon.com wrote: In a desktop environment this makes sense. However in some other contexts, such as real time embedded programming, it likely doesn't. And the issue there is the difference between average running time and worst case running time. I'd kiss you right now if I could... ;) I'm suddenly glad I live on the opposite side of the continent. :-P Ben ___ Boston-pm mailing list Boston-pm@mail.pm.org http://mail.pm.org/mailman/listinfo/boston-pm
Re: [Boston.pm] Exceptions as control flow
From: Ben Tilly bti...@gmail.com Date: Fri, 19 Mar 2010 11:34:41 -0700 On Fri, Mar 19, 2010 at 11:07 AM, Conor Walsh c...@adverb.ly wrote: I'm curious. Maybe I'm out of my depth, pun not intended, but I was under the impression that thrown exceptions have to unwind the stack anyway. Is there some way exceptions are usually implemented that doesn't cost as much as unwinding the stack one level at a time? The issue is this. If you don't use exceptions then you have to have if checks on every return for exceptional conditions. Those checks are individually fast, but there are a lot of them . . . And, critically, those tests must run on *every* invocation, not just in an exceptional situation. If there are loops, of course, it's that much worse. This is a fantastic discussion and I'm happy to see it here. It is surprisingly involved and detailed. I've been happy to read through it. Ben Ditto. From: John Redford eire...@hotmail.com Date: Fri, 19 Mar 2010 14:55:45 -0400 Also (relative to Ben Tilly's mail), it is possible to use techniques like maintaining a table of current handlers and using dynamic jumps in order to bypass uninteresting stack frames and hop directly to the finally code that calls destructors such, and to the handler for the exception being raised. That is (IME) the usual implementation (it actually uses a linked list), which means that you pay the price at runtime only for frames that actually require finally handlers. Of course, if a given implementation presumes Exceptions are always errors, it may walk the stack anyway and build up a whole data structure that describes where the exception took place. That would indeed be fairly slow to say the least . . . Better is a language design where the handler runs in the dynamic context of the exception, and gets to decide what to do, and how much information to capture. Like Perl 6. (Does this mean we're back on topic now? ;-) -- Bob Rogers http://www.rgrjr.com/ ___ Boston-pm mailing list Boston-pm@mail.pm.org http://mail.pm.org/mailman/listinfo/boston-pm
Re: [Boston.pm] Exceptions as control flow
When I said exceptions are just flow control, I meant it in the broad, almost-trivial machine sense. But then your point has nothing to do with marketing. All languages can do exceptions, and all exceptions translate into either branches in assembly or the hardware seeing a physical interrupt, storing off it's state, reading a vector table, adn jumping to that. From a marketing perspective, the question is whether or not Perl has the kind of exception syntax and paradigm to solve someone's problem. Any given language model can implement them in a way that makes it inappropriate to use them that way; but that's the basic idea as modeled by setjmp/longjmp. If every method is re-entrant, there is nothing to worry about because stack unwinding deals effectively with method-local state. But as soon as methods start affecting the longer term running state of a system, exceptions can easily leave that system in an inconsistent, possibly broken state. This is why many languages provide TRY...FINALLY, eh? And others use lexically guaranteed destructors to the same end. That Perl provides neither is one of the flaws in its exception handling. True, bad code can do all that without the benefit of exceptions. But, even otherwise solid code can go horribly wrong because exceptions are thrown in a 3rd party library. Non-throwing code is much, much less likely to have that impact. One can make the same form of argument against using threads, objects, etc... Things can go horribly wrong in many ways for many reasons. One of the problems with the Perl You can have exceptions if you want them approach is similar to that of C's Threads arrived later -- lots of code assumes no one will be using exceptions/threads, so is not safe in the presence of those things being added. An advantage of the Java We have threads exceptions -- they may be implemented badly, but they're always there approach is that all programmers are aware that those things are there, and they (if at all competent) make some plan to deal with it. (Typically badly, but safely.) This is the reason why coding standards for systems with very high uptime requirements often disallow throwing exceptions. This can extend to disallowing use of libraries that throw (or taking pains to configure libs so that they do not). This is one of those things which is pseudo-true. Obviously, neither using nor avoiding flow control is a guarantee of uptime. (Though perhaps not using flow control is a guarantee of minimal uptime.) What this policy is really saying (as I'd read it) is that, in an effort to avoid program defects, the program behavior should be kept as simple and obvious as possible. Which is fine. Until/unless you reach a point where it conflicts with another requirement, such as hard, real-time performance. Say you have code in a tight loop which has to call N functions, and if any of them returns X (which isn't considered an error), it has to return. Without exceptions, that means performing N tests. With exceptions, it requires no tests at all -- the functions themselves can simply throw 'X' when it happens. And before (or just after) you think it -- yes, that's a very vague example fraught with potential alternatives. But, it expresses a good use-case for fast, goto-like, not-just-for-errors exceptions. (Just to mention, an alternative, similarly efficient approach is to use continuations of some type and allow each function to decide between passing control to keep-trying or to X-happened alternatives.) Put another way, the rare nature of Exceptions (go figure) is implied in the sub-optimal treatment given by compiler writers to exception code paths. You sure as heck don't want to optimize Exceptions at the expense of the regular, non-Exception code paths! Slow exception implementations are suitable only for rare code-paths. But that does not mean that setjmp/longjmp are slow and can only be used rarely. You're somewhat inverting the cart and horse. Also, there is little or no tradeoff (this can depend on the CPU) for having exceptions present in a language -- but once you allow them at all; you have paid the penalty. (The penalty is related to return and try...finally -- essentially, every return must become equivalent to an exception, so it will hit the finally handlers properly. Or, similarly, so it will call destructors.) Once present, the speed of exceptions is only constrained by how much stuff one adds on top of the longjmp-or-equivalent implementation. For example, if every exception starts by tracing the stack gathering debug information that can later be used in an error message.. that's going to be a little slow. A language can offer the programmer a choice of throwing fast or slow exceptions, depending on what they're used for. ___ Boston-pm mailing list
Re: [Boston.pm] Exceptions as control flow
Charlie Reitzel wrote on Wed, Mar 17, 2010 at 07:11:55PM -0500: I was quietly reading this thread, but I must respectfully but strenuously disagree with the premise that exceptions are simply another kind of flow control. OK, semantically exceptions _are_ another type of flow control. Let's not jump down a rathole. FWIW, in C++ as of today's gcc, a function exiting with a thrown exception is roughly 1000 times more expensive than a regular call/return, and that is with one single object to clean up on the stack that sets one global variable. I can provide my little test program. I just had to kill some instances in my employer's codebase that were using thrown exceptions as regular flow control. They also make debugging harder since gdb by default jumps on them. But, in any language, exception-safe code is much harder to write than most programmers realize. You word it like that means exceptions are hard. But it is even harder (and usually much uglier) to do the same make safe for continued program execution after an error when attempting to do cleanups around stacks of regular return calls that you have to shortcut to. This is the reason why coding standards for systems with very high uptime requirements often disallow throwing exceptions. This can extend to disallowing use of libraries that throw (or taking pains to configure libs so that they do not). Wouldn't that mean don't let exceptions escape out of the library? Not that I like either. In my mind, not using exceptions is almost a guarantee that there are resource leaks. The only reason why this can halfway work today is that we have humongous amounts of virtual memory and can have thousands of file descriptions. Martin -- %%% Martin Cracauer craca...@cons.org http://www.cons.org/cracauer/ FreeBSD - where you want to go, today. http://www.freebsd.org/ ___ Boston-pm mailing list Boston-pm@mail.pm.org http://mail.pm.org/mailman/listinfo/boston-pm
Re: [Boston.pm] Exceptions as control flow
On Thu, Mar 18, 2010 at 11:40:40AM -0400, Martin Cracauer wrote: ... This is the reason why coding standards for systems with very high uptime requirements often disallow throwing exceptions. This can extend to disallowing use of libraries that throw (or taking pains to configure libs so that they do not). Wouldn't that mean don't let exceptions escape out of the library? Not that I like either. In my mind, not using exceptions is almost a guarantee that there are resource leaks. The only reason why this can halfway work today is that we have humongous amounts of virtual memory and can have thousands of file descriptions. Heh, and using exceptions is also a guarantee that there are resouce leaks unless the programmer is well disciplined with RAII, has garbage collection (which only helps with memory resouces), or reference counted smart pointers. And even then they have to have designed well enough not to forget that they have some collection at top level or some global singleton that never releases a reference to some huge tree of objects. Too often it seems enough to say only, there are resource leaks. I guess you folks are probably reading better code than I am. Still, tell me you haven't talked to people who think it's perfectly normal acceptable practice to run servers with a wrapper of some kind that kills them and restarts them periodically. But for safety critical projects, the no rtti, no exceptions rule is pretty common isn't it? Not sure if it's justified or not, but very common from what I hear. Something to do with code verification, provability? Not that that gives any lessons for application code in other domains, necessarily. -- Mike Small sma...@panix.com ___ Boston-pm mailing list Boston-pm@mail.pm.org http://mail.pm.org/mailman/listinfo/boston-pm
Re: [Boston.pm] Exceptions as control flow
Mike Small wrote on Thu, Mar 18, 2010 at 01:07:52PM -0400: On Thu, Mar 18, 2010 at 11:40:40AM -0400, Martin Cracauer wrote: ... This is the reason why coding standards for systems with very high uptime requirements often disallow throwing exceptions. This can extend to disallowing use of libraries that throw (or taking pains to configure libs so that they do not). Wouldn't that mean don't let exceptions escape out of the library? Not that I like either. In my mind, not using exceptions is almost a guarantee that there are resource leaks. The only reason why this can halfway work today is that we have humongous amounts of virtual memory and can have thousands of file descriptions. Heh, and using exceptions is also a guarantee that there are resouce leaks unless the programmer is well disciplined with RAII, has garbage collection (which only helps with memory resouces), or reference counted smart pointers. Resources are more than memory. In the age of 64 bit virtual memory memory leaks are actually a comparably minor issue. File descriptors not closed, files not synced, TCP connections left hanging, messing up the list of forked children that you expect to return are much more severe issues. There resources are subject to the same limits as ever. Fighting those issues in long-uptime programs is much easier with exceptions than without. Forbidding them makes no sense, except specifically if you think your programmers are too dumb. Ironically, C++ of all languages is better off here since it has the same mechanism for guaranteed cleanup whether you use exceptions or not. In both cases you use destructors in stack-based objects. That is the result why C++ doesn't have a finally statement, BTW. And even then they have to have designed well enough not to forget that they have some collection at top level or some global singleton that never releases a reference to some huge tree of objects. Too often it seems enough to say only, there are resource leaks. I guess you folks are probably reading better code than I am. Still, tell me you haven't talked to people who think it's perfectly normal acceptable practice to run servers with a wrapper of some kind that kills them and restarts them periodically. Then you are not talking about a long-uptime program. But for safety critical projects, the no rtti, no exceptions rule is pretty common isn't it? Not sure if it's justified or not, but very common from what I hear. Something to do with code verification, provability? Not that that gives any lessons for application code in other domains, necessarily. No rtti means casting things around without language support. No exceptions means deeper nesting of if statements and/or lots of if-return pairs. And it means infecting functions that are somewhere in the call tree between what would be the thrower and what would be the catcher with addition logic to deal with early returns, when they actually have no interest in either rising or dealing with that error. This screws up code readability even more than jumping through those functions. It is also not change tolerant since people might insert new function calls and might never actually see the raiser or catcher and have no clue about the set of possible exceptional cases that loom below. The rule should be to only let programmers who know what they are doing write safety critical code. Martin -- %%% Martin Cracauer craca...@cons.org http://www.cons.org/cracauer/ FreeBSD - where you want to go, today. http://www.freebsd.org/ ___ Boston-pm mailing list Boston-pm@mail.pm.org http://mail.pm.org/mailman/listinfo/boston-pm
Re: [Boston.pm] Exceptions as control flow
But for safety critical projects, the no rtti, no exceptions rule is pretty common isn't it? Not sure if it's justified or not, but very common from what I hear. Something to do with code verification, provability? I'm a little rusty, but my memory of life-critical avionics certification was that they do not allow exceptions, or dynamically allocated variables (malloc), or even stack type variables (my). The Boeing 777 had a whole bunch of code that got executed at regular intervals. some stuff ran at 120 hz. most ran at 30 hz. I don't know how they did the timnig synchronization to make sure they didn't run too fast, or how they detected if they ran too slow. But the code I was working on was basically nothing but Q-notation arithemetic that mapped to control logic diagrams written by the aero guys. inputs might be sensor data or outputs from other calculations, outputs would be either control surface control values or variables to other blocks of code. Control flow was extremely rudimentary. There migth be an if loop to make sure you dont' divide by zero. occaissional range checks were probably the most common control flow structure. I don't remember ever seeing a for loop. Object oriented anything was completely out. All variables were static package variables. Ada packages prevented them from being global and so made sure no one else mucked with your data, but they were static, compile time variables. Basically, pretty much all the code always executed every time it got called, and it was supposed to get called at a fixed frequency. Code coverage was meaningless, since almost everything executed on every call. Instead we looked at coverage from a data perspective. Verification consisted of inputing data at min, min+1, middle, max-1, and max for all the input variables and making sure the outputs were in the ranges specified by the documentation to make sure the aero guys got their numbers right and make sure the code compiled and executed correctly. And it was all Q notation (integer math) written in Ada because verifying/certifying floating point algorithms and floating point hardware would have been insane. I do know that non-life critical avionics (an LCD panel that acts like an artificial horizon in the cockpit) did not require nearly as strict requirements. We could do for loops and other more cmoplicated control flow structures. But we had to guarantee our worst-case execution time was always under some fixed amount. It ran at 30 hz or similar speeds as well. The stuff I worked on was again all integer math/Q notation. One algorithm I wrote was an inverse sine function that took in a number and returned the angle. It did a binary search on a table, found the two entries closest to the input, then interpolated between them for the final value. Given teh table size, you could guarantee, by design, what the worst case delay it would take for the function to return. Not that that gives any lessons for application code in other domains, necessarily. If I remember correctly, the hardware on the 777 consisted of three processors built by three different manufacturers (in case one manufacturer had a bug) all running the same code with hardware voting logic and such to flag a bad calculation. Not something you'd see in a web server company. I talked to someone more recently who was working on some cockpit display box. The FAA had loosened their requirements to teh point that they were goign to use C or C++ and use dynamically allocated variables. Malloc or soemthing. I don't know if the FAA has similarly loosened their requirements for life-critical avionics or not. But I guess I'm old-school when it comes to life-critical applications. Most code has bugs and most coders write buggy code . And the only way you'er going to achieve hundreds of thousands of hours of hardware/software operation without a single glitch is if you keep it simple stupid. ___ Boston-pm mailing list Boston-pm@mail.pm.org http://mail.pm.org/mailman/listinfo/boston-pm
Re: [Boston.pm] Exceptions as control flow
On Thu, Mar 18, 2010 at 01:30:13PM -0400, Martin Cracauer wrote: garbage collection (which only helps with memory resouces), or reference counted smart pointers. Resources are more than memory. In the age of 64 bit virtual memory memory leaks are actually a comparably minor issue. File descriptors not closed, files not synced, TCP connections left hanging, messing up the list of forked children that you expect to return are much more severe issues. There resources are subject to the same limits as ever. Fighting those issues in long-uptime programs is much easier with exceptions than without. Forbidding them makes no sense, except specifically if you think your programmers are too dumb. Alright, instead of trusting to memory or speculating, I looked up a reference, the coding standards for the UK joint strike fighter which I've read Bjarne Stroustrup refer to positively. I dunno if this is a good example for safety critical code, though. Well, if you mean the safety of the pilot and not the poor chumps having missiles lofted at them, I guess it works. So under fault handling it does indeed ban C++ exceptions, but the justification is interesting: AV Rule 208 C++ exceptions shall not be used (i.e. throw, catch and try shall not be used.) Rationale: Tool support is not adequate at this time. http://docs.google.com/viewer?a=vq=cache:fHgIT0Zu_P8J:www2.research.att.com/~bs/JSF-AV-rules.pdf+MISRA+C%2B%2B+bjarne+stroustruphl=engl=uspid=blsrcid=ADGEESjlTYI0nFwSyxHaMn_cXYGKReDQS31JjEas9PEZMTbErDkUwZCs_9JlZ7MADYsQAvX4UUwQDEMCkzcaFc7LrDoH3cd-GdXGlrVzmx6BUZ1eky8AT-q0NVoimfIoVWNS4uR-vWXRsig=AHIEtbQ5w66vhoDhSfhneEmnNFbB4CShZQ So anyone have a guess at which tools they mean? The compiler itself or testing and verification tools? at top level or some global singleton that never releases a reference to some huge tree of objects. Too often it seems enough to say only, there are resource leaks. I guess you folks are probably reading better code than I am. Still, tell me you haven't talked to people who think it's perfectly normal acceptable practice to run servers with a wrapper of some kind that kills them and restarts them periodically. Then you are not talking about a long-uptime program. Well, the intention generally is that servers be long uptime I'm sure, but there aren't enough non-dumb programmers apparently. Truly, you've never encountered a system administrator who follows this practice without complaint (or at least without surprise)? ... The rule should be to only let programmers who know what they are doing write safety critical code. I hope only the best write this kind of code, but if the #1 rule was that where we need perfect systems we will get them by using perfect people, well, I think I'd do a lot of walking to get around, preferably on country paths far from any machinery with computers in it. It does seem that some embedded programmers use this practice of avoiding parts of their languages. Perhaps they have some justifications. -- Mike Small sma...@panix.com ___ Boston-pm mailing list Boston-pm@mail.pm.org http://mail.pm.org/mailman/listinfo/boston-pm
Re: [Boston.pm] Exceptions as control flow
So anyone have a guess at which tools they mean? The compiler itself or testing and verification tools? When you are working on a life-critical avionics (LCA) project, everything must be certified to the same stringent requirements. That means the compiler must be certified as strictly as the software being compiled. Same goes for hardware. you can't just use any old processor off the shelf for LCA. As for validation tools, the 777 ran the code on the actual hardware. Testing was done by halting the code, inserting the data, letting it run for a frame, stopping the code, and getting the results. The idea, I guess, was to verify the source code, the compiled code, and the hardware all at once. The rule should be to only let programmers who know what they are doing write safety critical code. I hope only the best write this kind of code, but if the #1 rule was that where we need perfect systems we will get them by using perfect people, No. building some LCA black box isn't about perfect individuals. It's a team effort. At an absolute bare minimum, assuming you start with certified hardware and a certified compiler, the FAA requires that you have at least two people working on the project: One person designs, the other person verifies. If you want, you can have Alice write the code for the take-off/go-around piece, and have Bob verify it; and then have Bob write the code for the stall recovery piece, and have Alice verify it. But no single person gets to write code and ship it without at least one other pair of eyes verifying that it's good. At which point, you get the skydiving analogy. One parachute has a 1-in-N chance of failure. Two parachutes have a 1-in-(N*N) chance of failure. If N is 1000, then 1 parachute means 1 in a thousand skydivers die because of chute failure if they use a single chute. And 2 parachutes means that 1 in a million skydivers die from parachute failure. in it. It does seem that some embedded programmers use this practice of avoiding parts of their languages. Perhaps they have some justifications. most embedded applications have to refresh at a certain rate. say 30 hertz. If you have exceptions and dynamically allocated variables with garbage collection and objects being instantiated and destroyed on the fly and any other kind of open-ended software construct in your code, how do you guarantee that you can refresh at 30 hz? It's not a language problem. It's not a construct problem. It's not that embedded folks don't know that exceptions are nothing more than jumps. When it comes down to it, it's a *system* issue. When all the pieces come together, and they are designed from the ground up to do this, and if an interrupt happens stop and do that, then how do you guarantee a 30 hz refresh rate? What if you're refreshing the data that controls the fuel injectors in your car or the shifter on your automatic transmission? If you code from the ground up using constructs and designs that don't take into account refresh rate, then you cannot guarantee refresh rate. And if you don't refresh fast enough you may over-accelerate your car because you're feeding too much gas, you may strip the gears in yoru transmission because you're not shifting fast enough, or you might crash your airplane because you're not responding to the pilot's commands or the values on the pitot tube. Embedded engineers have to use constructs that can guarantee refresh rate. THey have to design teh system so that there are no exceptions, because they can't guarantee how long any particular exception will take, or how many exceptions they might get at any particular time. That generally means you have to poll all your sensors at a fixed frequency. and you can only respond to incoming data at a fixed rate. Folks who are used to writing code for desktop applications want their code to run as fast as possible and only deal wiht odd bits and pieces when they absolutely have to. It all really comes down to focusing on best-case or worst-case execution speeds: desktop people generally focus on trying to make their best-case speed as fast as possible, and every once in a while, their worst case will bog down because someone is loading a webpage with video while netflix is streaming a movie to their harddrive while they're listening to an MP3 that is decodign with software, and their computer freezes up for a few seconds, and everyone just shrugs it off as nothing more than an annoyance. embedded engineers have to focus on making sure their worst-case delay is below some minimum. They *have* to maintain a refresh rate of 30 hz or something physical breaks or someone could get hurt. I remember learning this lesson when I was working on that cockpit avionics project. I had an idea for how I could speed up some line-drawing algorithm we had written. The architect rejected it because even though it would have made it a third faster most of the time, there would be some cases where it would have
Re: [Boston.pm] Exceptions as control flow
On Thu, Mar 18, 2010 at 01:46:43PM -0500, Greg London wrote: So anyone have a guess at which tools they mean? The compiler itself or testing and verification tools? When you are working on a life-critical avionics (LCA) project, everything must be certified to the same stringent requirements. That means the compiler must be certified as strictly as the software being compiled. Same goes for hardware. you can't just use any old processor off the shelf for LCA. It strikes me that would be almost out of the question, or at least very expensive, for anything as complicated as a C++ compiler. And yet I hear that C++ is beginning to be used for more and more embedded work, if perhaps not the LCA projects you're referring to. It's interesting to get this perspective. So different from anything I've worked on (thank goodness, at least for the sakes of airline passengers). -- Mike Small sma...@panix.com ___ Boston-pm mailing list Boston-pm@mail.pm.org http://mail.pm.org/mailman/listinfo/boston-pm
Re: [Boston.pm] Exceptions as control flow
Greg London wrote: [...Lots of fascinating stuff removed...] It's not a language problem. It's not a construct problem. It's not that embedded folks don't know that exceptions are nothing more than jumps. And yet they do use jumps, no? When it comes down to it, it's a *system* issue. When all the pieces come together, and they are designed from the ground up to do this, and if an interrupt happens stop and do that, then how do you guarantee a 30 hz refresh rate? Well, interrupts aren't exceptions. But one could say the same with any 'if' test a jump, no? Isn't the answer is that you ensure all code paths finish in time? [...] Embedded engineers have to use constructs that can guarantee refresh rate. THey have to design teh system so that there are no exceptions, because they can't guarantee how long any particular exception will take, or how many exceptions they might get at any particular time. Well, you get one exception at a time, much like you get one if or goto or return at a time. No different than jumps. This again seems like you're talking about interrupts. That's a whole different issue. If you don't want interrupts, then you don't want interrupts, regardless of them subsequently triggering exceptions, gotos or anything else. Of course, when you are in code that does not have stack frames, then (arguably? not arguably?) you can't have anything that would reasonably be called an exception -- it's just a goto/jump. So it's a bit moot. But if you have a call stack, and you want code to execute quickly in order to meet a time constraint (hard or not), then the idea is to use exceptions-as-goto to avoid testing return codes (perhaps redundantly). A classic (but loaded) topical example is reading a file (or whatever) until EOF. EOF is not an error -- it could never seriously be argued that it's an error for files to have an end. If you're using a random-access API, then it's indeed probably an error to ask for data outside the file; but when you're using a stream-like API, then it's simply bound to happen that you say next() and get EOF. Now, checking every next() call to see if it returns EOF (or sets some EOF flag variable) is inefficient, relative to having next() throw an exception -- essentially jumping directly to your code in the place that's supposed to run when the stream is emptied. ___ Boston-pm mailing list Boston-pm@mail.pm.org http://mail.pm.org/mailman/listinfo/boston-pm
Re: [Boston.pm] Exceptions as control flow
Well, interrupts aren't exceptions. sorry, I'm programming an interrupt controller right now. wires got crossed. you have a call stack, and you want code to execute quickly in order to meet a time constraint (hard or not), Now, checking every next() call to see if it returns EOF (or sets some EOF flag variable) is inefficient, You're not thinking like an embedded controller engineer. You're trying to make your best case run faster. An embedded guy has to get their code to run at some frame rate. Say 30 hz. His code has to run one frame of data every 33 milliseconds. and then the processor goes to sleep until the timer wakes it up for the next frame. What does it mean if you're code is more efficient but still runs at 30 hz? You're talking about the problem like someone used to programming for desktops. Make things run as fast as possible and slow things down as needed to get done. For example, you'd never read a file of unknown length in avionics or any kind of embedded controller application like an engine controller. At least not on a per-frame basis. You might dedicate so many clock cycles per frame to read some fixed number of bytes per frame, but you wouldn't have code that says read until EOF and then code it with an exception so that you respond to EOF more efficiently. You're trying to make your best case better, and you worst case is how ever long it takes till you read EOF. Embedded controller guys have to make their worst case meet some minimum. And no open-ended processes are allowed per frame. ___ Boston-pm mailing list Boston-pm@mail.pm.org http://mail.pm.org/mailman/listinfo/boston-pm
Re: [Boston.pm] Exceptions as control flow
I was quietly reading this thread, but I must respectfully but strenuously disagree with the premise that exceptions are simply another kind of flow control. OK, semantically exceptions _are_ another type of flow control. Let's not jump down a rathole. But, in any language, exception-safe code is much harder to write than most programmers realize. If every method is re-entrant, there is nothing to worry about because stack unwinding deals effectively with method-local state. But as soon as methods start affecting the longer term running state of a system, exceptions can easily leave that system in an inconsistent, possibly broken state. True, bad code can do all that without the benefit of exceptions. But, even otherwise solid code can go horribly wrong because exceptions are thrown in a 3rd party library. Non-throwing code is much, much less likely to have that impact. This is the reason why coding standards for systems with very high uptime requirements often disallow throwing exceptions. This can extend to disallowing use of libraries that throw (or taking pains to configure libs so that they do not). Put another way, the rare nature of Exceptions (go figure) is implied in the sub-optimal treatment given by compiler writers to exception code paths. You sure as heck don't want to optimize Exceptions at the expense of the regular, non-Exception code paths! At 12:03 PM 3/17/2010 -0400, John Redford wrote: Which begs the answer to your question: Yes, people use die as goto. People use longjmp as goto. People use throw as goto. Exceptions have an association with concepts like error case and should rarely happen; but that is entirely wrongheaded. Exceptions are simply another kind of flow control. There are some low-level implications in terms of CPU efficiency, but it's just a matter of unwinding the stack until a point is found where some code should run, and then adjusting the instruction pointer. Within a single stack frame, it reduces to simply being a goto. Some languages (Perl, Java, others...) approach exceptions as rare and so have implementations that deter their use in high-performance scenarios -- so it's often a question not of program structure, but optimization and frequency. ___ Boston-pm mailing list Boston-pm@mail.pm.org http://mail.pm.org/mailman/listinfo/boston-pm