The company I work for contracts us to a customer which is a large government-controlled entity, hereafter GCE. Our task there is to maintain the zillion of in-house applications they use, aka The System.
Applications from The System generally suffer from a number of ailments, from not-invented-here syndrome to just-plain-crap syndrome and not-understanding-wtf-we-are-doing syndrome, aka cargo-cult programming. An example of the former would be that using bools is deprecated. Instead, there are Booleans. And what is a Boolean? A typedef for a short, of course. In which way is it better than a bool? Why, it was developed at GCE, silly! We have it in a source file in our code base, along with two homemade consts YES and NO instead of these foreign true and false! Sadly, this is probably one of the sanest and most harmless examples we have around -- no, there is no FILE_NOT_FOUND, and YES does not equal 0 either.
An example of the latter could be the following paradigm. As we all know, duplicating code is bad. And classes often have several constructors that perform mostly similar tasks, except for the bits where the parameters are involved. So, in just about every class in The System, the constructor only copies its parameters in the newly created object, then calls void Classname::constructor(void) which performs the actual work. Still not so bad, you say? Well, here's the kicker: destructors are subjected to the same rules.
However, this pales in comparison with what I've found the other day. I was wading through the code of the mother class of a MDI application, and found this:
void AppSomething::destructor(void)
{
if (m_pChild1 != NULL) {
if (m_pChild1->isDestroyed() == NO) {
delete m_pChild1;
}
}
if (m_pChild2 != NULL) {
if (m_pChild2->isDestroyed() == NO) {
delete m_pChild2;
}
}
// snip the same code repeated for every child frame
// and then other stuff
}
Dear God, I thought, please let it not be as stupid as it looks. Alas, God had forsaken me this day.
Boolean GceChild1::isDestroyed(void)
{
return m_bDestroyed;
}
Aside from the member definition in GceChild1.h (private, so God in fact had had a little mercy on my soul), a search returned just two other mentions of m_bDestroyed:
void GceChild1::constructor(void)
{
// snip real work
m_bDestroyed = NO;
}
void GceChild1::destructor(void)
{
// snip real work
m_bDestroyed = YES;
}
(Of course, the same monster was copypasted in every GceChild class from 2 to I-don't-remember-how-many.)
I guess whoever wrote that wanted to really, really make sure the application wouldn't go and delete stuff it no longer owned.
jaywalker
@jaywalker
Best posts made by jaywalker
Latest posts made by jaywalker
-
The secure destructor
-
RE: You should not believe what we say
@Random832 said:
The proper response:
- Why is your website full of lies? I demand to speak to the person responsible!
Or something like that.Yeah, you try this in a French administration. At best, the employee will roll her eyes and tell you to please stop wasting her time. At worst, security will be called and you will be thrown out on your arse.
-
RE: Please remove error message. Thanks.
@alegr said:
How about using a login script to map a home directory on a server, and then use WritePrivateProfile*. No need to be fancy with a database.
That would technically have been a possibility. However, it wasn't an acceptable option: they love their database, so the more stuff they store in there, the happier they are.
Anyway, I said in the OP I had added a preferences dialog to an application. That wasn't the whole truth. I had added a preferences dialog to two applications. Yesterday, the same person finally got around to testing the second application. Which, naturally, also stored its preferences in the database. I'll let you guess what were the first and second problem ticket I received. *facepalms*
-
RE: Please remove error message. Thanks.
@alegr said:
The only reason to fail "Save Preferences" is "access denied". This happens when an illiterate programmer uses WriteProfileInt (which is completely old stype) or HKEY_LOCAL_MACHINE/Software/<your company name>.
Not quite. In fact, they want their users to be able to launch the application on any workstation and have access to their preferences. Therefore, registry or ini files were ruled out, and we had to store the preferences in a database table. The error message came when the database server failed. (For the record, it turned out the table was not created correctly on the test environment.)
By the way, storing stuff in a text file may be old style, but I fail to see why it would be worse than storing them in a binary registry.
-
Please remove error message. Thanks.
I have been adding a preferences dialog box to an application used by a customer. I deliver, they run their tests, and today I receive a number of problem tickets and change requests.
Problem ticket #1:
Description: I do such-and-such. I click the "Save preferences" button. I quit the application, then launch it again. The preferences entered in the previous session are lost.
Action requested: Keep the preferences between sessions.
Problem ticket #2:
Description: I do such-and-such. I click the "Save preferences" button. An error message "Could not save preferences" pops up.
Action requested: Remove the error message.
Both problem tickets were issued by the same person. I wonder if she thought that the error message would pop up at random just to annoy her, and that it was by a lucky coincidence that every time it would pop up, the preferences would not be saved...