3 ms·
> Make sure your loops terminate. Bounded loop variants that increase or decrease strictly monotonically guarantee loop termination. Don't be too clever with lo
by lifthrasiir 5y ago
> Make sure your loops terminate. Bounded loop variants that increase or decrease strictly monotonically guarantee loop termination. Don't be too clever with loops!
More generally, isolate any non-simple loop into a dedicated function that calls a callback and make use of such functions throughout the API. Not just because of testability but also because an inlined loop is very hard to track as is. It can even be said that async functions exist partly in order to eliminate an event loop tucked in a state machine. Alas, this observation is not really actionable in C.
- hinkley 5y agoYou can always go through and clever up the two or three complex loops that will actually create a substantial performance benefit. But leave the rest of them dead boring. I think a lot of times we write code as if this is the final form it's going to be in. Five features later, we're hardly going to recognize it, and each change is a wedge that can open up a chink in the logic and introduce a nasty bug. If you start clever, there's nowhere to go but down.
- couchand 5y agoUnfortunately we're terrible at prediction. The code you spent all night getting clever with gets rewritten next week, but the code you just threw together survives until the new platform, when it gets ported directly because nobody remembers why it was written like that.
- kazinator 5y agoLoops that depend on some graph (say, mutated in place) to reach a fixed point can present a challenge here. You have to reason about the algorithm that changes the values at the graph nodes, and whether it guarantees forward progress toward a fixed point. Floating point convergence is another risky thing in this category. If you're iterating to convergence, the test has to nail it, and if there is any risk of it going sideways, there has to be some exit strategy baked in. I think more than once in the past I've added a maximum count to some loop that might not otherwise terminate, more than generous enough not to trigger as a false positive. I seem to recall that Donald Knuth's TeX famously has some infinite looping detection in some of its formatting code. I can't find any references to this via web searching, though. Another category are mutually tail-recursive functions. The termination of a tail-recursive network of functions could be as hard to prove as a goto graph. Introducing a maximum iteration count could mean adding a count parameter to many of the functions, passing count -1 and checking for dropping to or below zero in more than one place.
- LorenPechtel 5y agoYeah, more than once I've coded suicide counters into indeterminate loops to catch corrupted graphs. And recently I had a fairly simple user-created graph that I forgot to put a suicide counter on. Of course I found out the omission the hard way. What did you expect it to do when you said A waits on B, B waits on C, C waits on D and D waits on A??? (Actually, the main part worked so it didn't immediately smack him in the face. However, there was a routine to find the completion time, if an item didn't exist use the completion time of it's parent(s).)