|
One of the rules I follow when programming is never to make infinite loops. For-loops with an explicit test on an iteration counter are reasonably "safe", and I prefer those when they don't mess up too much.
Sometimes while-loops come a lot more natural. Unless there are other explicit and obvious tests that guarantee loop termination, regardless of (loop) external conditions, I always add something like
int iterationCount = 0;
while (<some 'unsafe' condition>) {
if (iterationCount++ > 10000) break; The limit is arbitrarily chosen, but must of course be larger than the actual iteration count in any 'normal' situation. If the loop still runs after (say) 10000 iterations, something is surely wrong.
Yes, it takes two extra lines. It takes a couple of extra instructions for each iteration. But it makes sure that the code never is stuck in an infinite loop when it shouldn't.
|
|
|
|
|
I use techniques like that and usually make the safety stop a multiple of the container size being processed.
I always use this pattern when I am removing processed items from a list and expect the list to be empty as the normal loop termination.
After loop exit, dump any items that do remain in the list
|
|
|
|
|
It's been awhile so this story may be dated. I was using some recursive tree balancing code I got from Dr. Dobb's Journal (for the young-uns very cool magazine). It was very solid and got used all over the place. Decided to test it with windows 10 (64 bit) visual studio. Once recursion hit 64 levels, windows halted the program with no messages, errors or otherwise. Just quit. Not documented that I could find, so go figure. Sort of the like the 1000 limit you encountered. A hard round number clearly not an accident.
"A little time, a little trouble, your better day"
Badfinger
|
|
|
|
|
I'm curious: What did the 64+ recursion levels express? My first guess is that descending one level in the tree would lead to another recursion level. But did you really handle a tree 64 levels deep? What the elephant kind of information did that tree store? What kind of tree was it? Binary? Even if binary, it would have to be extremely unbalanced if it had a 'reasonable' number of nodes, yet 64 levels deep.
Even if recursing was used for other uses than descending one tree level, exceeding 64 recursion levels is almost always a result of a faulty termination test, or a data structure fault (such as a circularity in a tree), or some other error. Mathematicians are allowed to use unbounded recursive definitions, but it doesn't map well to program code
Obviously, you should have been given some sort of error message. I have had stack overflows that were not caught, just crashing as you report your program to do; chances are that the real problem was a stack overflow. I have worked with people who strongly object to all sorts of 'unnecessary' runtime tests, arguing that if you really need more stack space, it is your responsibility to set it up, not the runtime code to check for it. Maybe those who made the runtime system you were using was of that kind.
|
|
|
|
|
The input to the tree balancing code was a sorted list of names (tree n-deep) and various versions of randomly listed of names (random distributed tree of mixed depths). Don't recall how long the lists were but pretty long.
I was curious about the code, because it was so terse and worked like magic if not for stack overflow. Somewhere I have that old code. If I find it I will post it.
I agree that one should make ones own stack, because you can control the stack depth and test for circularity, etc.
I have written a number of tree libraries (n-nary mostly) and that's way I do it.
"A little time, a little trouble, your better day"
Badfinger
|
|
|
|
|
|
Yes, I aware of these earlier journal's. Had a subscription for many years.
Balance tree code come from a 1992 Dr. Dobb's (I think Jan. edition)
"A little time, a little trouble, your better day"
Badfinger
|
|
|
|
|
Yes, balanced binary tree is result of routine.
"A little time, a little trouble, your better day"
Badfinger
|
|
|
|
|
use
SELECT TOP (1000) instead of
SELECT TOP (1024)
"In testa che avete, Signor di Ceprano?"
-- Rigoletto
|
|
|
|
|
The old Macs counted 1000 bytes as a kB.
They always boasted to have 2.4% more disk space than DOS/ Windows with the same hard drive.
|
|
|
|
|
Disk manufacturers always specify capacity in decimal units - kilo, mega, giga, tera. I recently bought a 16 tera disk: 'Properties' says that it holds 16 000 881 782 784 bytes, or 14.5 TB. (It is a pity that Windows won't use the proper unit, Te bytes, not T bytes!)
Network people also use decimal units. Plus, they count bits, not bytes. When we switched from analog modems to ISDN, some people where complaining loudly: They expected a B-channel to carry 65 536 bytes/sec, while it did carry 64 000 bits/sec (or 8000 bytes/sec).
|
|
|
|
|
ISDN was the most short lived internet technology in my area. I was glad the company I was working for at the time loaned me the $1000 modem to use it.
It was better than dialup because it would use both 64000 bit digital channels. And the digital “call” would complete sub second versus the old audio modem dial and handshake.
Due to Mother Nature taking out the old DSL system in my current neighborhood, we were upgraded to optical fiber.
|
|
|
|
|
That reminds me of my favorite hour long (at least) debugging session a long time ago in C++, wondering why the loop executed only once (therein lies the fault of my expectations, lol). Here's the essence of it:
for (int i = 0; i < 10; i++);
{
}
|
|
|
|
|
Been there, done that.
Soooooooooooooo frustrating.
"In testa che avete, Signor di Ceprano?"
-- Rigoletto
|
|
|
|
|
At least with C#, Visual Studio would give you a warning.
I haven't been working with C(++) in Visual Studio for quite a while, so maybe it is limited to C#. Another side of the coin: I sometimes make code where empty statements do make sense, so I have to ignore the warning. But I never make {} blocks for no explicit reason. (Note: Variable declarations within the block is a good reason.) So in a case like this, I would rather prefer a warning about redundant {}s.
|
|
|
|
|
My version of that:
if (condition)
{
}
{
}
Software Zen: delete this;
|
|
|
|
|
Thanks for deleting the unnecessary comment from my original check in.
if (condition)
{
}
{
}
|
|
|
|
|
This isn't a sign you need more coffee. It's a sign you need to head to the nearest pub and call it a day.
|
|
|
|
|
Well, it is past 9am...
cheers
Chris Maunder
|
|
|
|
|
FYI, after invocation of a couple minor deities, if it's 9:00 am in Toronto, it's 11:00 pm in Canberra.
Through inheritance, extrapolation, and a little jive you can therefore drink to your heart's content.
Software Zen: delete this;
|
|
|
|
|
A big chunk of my heart still lives in Canberra so I reckon I've got enough justification.
cheers
Chris Maunder
|
|
|
|
|
ALWAYS!
Get me coffee and no one gets hurt!
|
|
|
|
|
Your coffee cup is empty!
Freedom is the freedom to say that two plus two make four. If that is granted, all else follows.
-- 6079 Smith W.
|
|
|
|
|
Wordle 389 6/6
🟨🟨⬜⬜⬜
🟨⬜🟩⬜🟨
⬜⬜🟩🟨⬜
⬜⬜🟩🟩🟩
⬜🟩🟩🟩🟩
🟩🟩🟩🟩🟩
Just made it.
|
|
|
|
|
Wordle 389 3/6
⬛⬛🟩🟩⬛
⬛🟩🟩🟩⬛
🟩🟩🟩🟩🟩
|
|
|
|