If you’re a programmer, you should know this…
My initial post was going to be a snark-filled venting of all that ails me with my “day job” at the moment. Specifically, the woes of maintenance programming when dealing with a codebase from 2000 and ported from Windows to Linux.
If JP Sartre was a coder, he would have actually said:
“hell is other people’s (undocumented) code.”
So for your amusement, here is the list of simple mistakes I’ve seen of late. Consider these some simple C++ programming sins you may use to torment those that will follow you for eternity.
Inappropriate use of delete when you really mean delete[].
Performing a scalar delete on a pointer to an array deletes the first element only and leaves the rest of the array hanging around in memory. What a nice mess that leaves behind.
Inconsistently implementing basic idioms
eg reference counting, across multiple classes. Decide on the “one true way” and then put it in a base class, template class, whatever. Just Don’t Repeat Yourself (DRY).
Using naked pointers.
If you must insist on using pointers, adopt one idiom and stick with it. Don’t leave dangling pointers, whenever you delete a pointer, set it to NULL and use this as a guard condition, so you don’t try to delete it twice. eg
if (pFoo) {
delete pFoo;
pFoo=NULL;
}
This is mostly useful in the case where you have pointers as member variables of a class, which may or may not have been allocated and/or cleaned up before the destructor is called.
Not commenting code.
At all. What more can I say really? Maybe it was obvious to you when you wrote it, but it beats the life out of me whether the code does what you meant it to do. I’m not a mind reader or a savant. You’re not a savant either, but chances are I think you’re an idiot now I’m knee deep in your code and it’s a mess that I can’t decode.
Smart programmers recognise their own fallibility
… as well as seeing that trait in others. We’re imperfect, we all forget things now and then, there’s no point in being macho about the way we program. Better to be defensive, when you revisit the code 6 months later, you’ll thank yourself.
Here are some simple remedies:
- Use STL containers wherever possible (and sensible), rather than dynamic arrays. The benefits outweigh the performance hit in most non-trivial cases. If you must use arrays, pay close attention to how you delete them, or you’re eventually gonna get bitten
- Pay attention to patterns – extract common code wherever you can to save repetition. Make this code testable, so when it’s right, it’s right through your entire project.
- Instead of naked pointers, consider smart pointers, such as STL’s auto_ptr. Boost also features some more flexible smart pointers, including shared_ptr. Sure auto_ptrs don’t work so good for arrays, and you can’t store them in STL containers, but if you find yourself in either of these situations, you should probably rethink what you’re trying to achieve anyhow. If you program inside of this constraint you’ll save yourself in the long term
- Document your code. It doesn’t have to be verbose, but leave a few clues to jog your own memory. At the very least, try to document expected functionality and keep it in synch with the code itself. If you say in the comments that a function does “A”, it better do “A” exactly as advertised.
Seriously, this is all stuff I learnt in first year software engineering? Why are so called professionals still not capable of doing this?