While on the bench and being subjected to a bunch of tests to validate the seeker components against simulated targets and countermeasures, the flight control surfaces would start spazzing out after a few minutes in the test jig.
The problem had something to do with IR (or something) tracking and attitude control, with the tracker rolling over the odometer and sending spurious data to the flight guidance system which caused the tests to fail and would have lead to an in-flight breakup of the missile real-world.
The onboard hardware was highly resource constrained, and engineers and developers worked for weeks trying to fix the problem, going as far as contemplating a complete redesign of the seeker system.
Then somebody pointed out that between the time of launch and the missile's two end states: impact with the target or fuel exhaustion-- was less than 60 or so seconds.
The only reason the bug was causing problems was that tests were being run back-to-back-to-back in order to speed up things, and the seeker subsystem was being powered on for way longer than it ever would be in the real world.
A missile shouldn't have to be on for more than a couple of minutes, and a Dreamliner shouldn't have to be on for more than 248.55 days so I'm willing to bet they stuck some ancient 8-bit micro in there, reused ancient code that was already tested, and called it a day.
A Patriot Missile in Saudi Arabia wasn't launched to intercept a SCUD, which then killed 28 soldiers. The reason was poor handling of rounding errors [1]
The maiden flight of the Ariane 5 rocket resulted in a RUD due to an integer overflow [2]
[1] http://www-users.math.umn.edu/~arnold/disasters/patriot.html
[2] http://www-users.math.umn.edu/~arnold/disasters/ariane.html
Why stop there? Why on earth would anyone use an integer instead of a double, given the inherent risk of truncation error? Or for different arguments: Why on earth would anyone use a 16 bit wchar_t? Why on earth would anyone make char unsigned (or signed)? Why on earth would anyone put the little end first?
Machines are machines. They have fixed representations for different types, with tradeoffs. And you have to pick one. And the thing about timeout handling specifically is that everyone along the path from the timer driver up through the app needs to agree on the precision needed, or you'll get an overflow condition.
Arguments of the form "Bugs are bad and we shouldn't write them" have not historically helped with improving software quality.
If this bug were to appear every 200 years, that's substantially longer than the lifespan of any single airframe currently in existence (and nearly twice as long as the existence of powered flight) -- and if a Dreamliner were to actually survive that long (most likely as a historical artifact doing heritage flights, maybe), doing this kind of reset would just be part of the routine of getting the "old frame" up and running, not unlike timing certain steps of a WWII fighter plane's manually rather than having them done automatically.
Without saying that increasing the width of that variable is the _optimal_ solution, in this case deferring the error leads to safe and predictable operation over the airframe's nominal lifespan.
For what it's worth, quadrupling the variable's width to a int128_t would mean you can store over 10^22 years at nanosecond granularity, effectively future-proofing this bug out of existence, and I'm reasonably sure a modern system should be able to spare 3 extra bytes.
No, just no. Don't be a hilljack. Build something to spec. 32 bits is clearly not to spec.
You fix that with careful design and testing, not with "why on earth".
[1] As pointed out, it's not simple. Again, the whole stack need to agree with you and your concept of "to spec", not just the code you're personally typing.
I dunno but clearly running more than 248 days was not in it, otherwise this would hopefully have been caught and tested. If it was specifically specced to last N days and N < 248, personally I would have asked for my money back. As this appears to come as a surprise to everyone (caught late), I'm calling this one as I see it--a facepalm.
Fun fact: the C standard does not specify the width of wchar_t. While MSVC uses 16-bit wchar_t (UTF-16), gcc (even MinGW on Windows) uses a 32-bit wchar_t.
I agree, but the difference between 32-bit counters and 64-bit counters as a precision refinement is very special. Upgrading from 32-bit counters to 64-bit counters, even when counting nanoseconds, lifts you out of human timescales. No electronic system has ever or will ever need to maintain a microsecond count for 600000 years, for example.
Depends on what you're doing.
> Why on earth would anyone use a 16 bit wchar_t?
That's a very good question! Either use something that can hold at least 21 bits, or use UTF-8.
> Why on earth would anyone make char unsigned (or signed)? Why on earth would anyone put the little end first?
These have nothing to do with space, what weird analogy are you trying to make?
> They have fixed representations for different types, with tradeoffs. And you have to pick one.
For most purposes, there is zero benefit for going too small. Pick a number that can't break under the use it's getting. If a fixed-size number can't do that, change your algorithm.
> And the thing about timeout handling specifically is that everyone along the path from the timer driver up through the app needs to agree on the precision needed, or you'll get an overflow condition.
Making sure your data types are compatible should be one of the easiest pieces of analysis you're applying to your safety-important code.
> Arguments of the form "Bugs are bad and we shouldn't write them"
Yeah, this isn't that at all. This is "think about the limits of your data types as you pick them". A computer being left on for a year should be an expected use.
To understand this mindset, have a look at http://www.stroustrup.com/JSF-AV-rules.pdf