So I was a bit surprised the other day when I was reading Raymond's blog because he usually never has magic numbers in his example code. But he was doing GDI operations, like BitBlt, to demonstrate how to draw a masked menu graphic image.
So I was a bit curious where he got these magic numbers from, so I followed the link he posted to the raster operation codes page over at MSDN.
I must say, this is the worst designed API I've ever seen. It may be nice from the API designers point of view, and I can see how this affords a lot of flexibility to the programmer. But for cryin outside, just make an enum and name all those magic numbers! Any time you point me to a web page that has two tables with which I need to create a reverse polish notation string so that I can go to a third table to pull a hex representation of the string out of just so that I can complete a single raster operation (phew! That's a mouthful!), I'm going to point at you and tell you to get stuffed.
Which is more readable to the programmer?
BitBlt(pps->hdc, cxCheck, 0, cxCheck, cyCheck,
hdcMem, 0, 0, 0x00220326); // DSna
or
BitBlt(pps->hdc, cxCheck, 0, cxCheck, cyCheck,
hdcMem, 0, 0, kNotSourceAndDest);
Sure, some mappings may get long names, like 0x00351864 (SPDSxnox) becoming kNotDestXorSourceOrPatternXorSource, but at least it has a *name*. The programmer can always comment the intent if they feel it's not obvious (and they should put in plenty of comments!). But whenever I see magic numbers in code, my eyes are drawn to them and I immediately wonder "is that code right? I mean, there's no constant there, so how well thought-through could the code be?"
I think BitBlt has a nice, sensible parameter list. My gripe is with the magical raster operation codes not having names, and for that, I claim it's a horrible API. Thankfully Microsoft decided to name some of the most common operations (like SRCPAINT and SRCAND, etc).
Leave a comment