Defective C++: 'const' sucks
October 17, 2018This is part of my "Defective C++" series, not because it's a flaw in the language itself but because the culture that grows up around any language is effectively part of it and this is definitely a flaw in that culture. Don't get me wrong: I think const is a useful and perhaps even necessary language feature. The problem is the "const by default" attitude many people seem to have. I've now worked in multiple codebases where my predecessors seemed to think that adding const wherever they can automatically makes code better, and it always ends up being a pain in the ass. For example, I recently had to deal with the case where options for an I/O request were wrapped up into an object (another of my less-favorite C++ idioms BTW), then another method that passed the request onward very reasonably needed to add another flag ... but the passed reference was const. Yay. This leaves three choices.
- Remove the const modifier in every method between the one that created the object and the one that needed to change (five methods in three files IIRC).
- Cast away the const-ness. OK in some situations, but if it becomes a habit then const becomes meaningless. What if the original scope relied on the thing not changing?
- Make a copy of the object, and modify/pass that. This is what I did, because it was a small trivial object; in the more general case I probably wouldn't.
All of this could have been avoided if const hadn't been applied to a very transient object in the first place. People need to stop thinking of const as something to add unless there's a specific reason not to, and think of it as a tool to use when there's a specific reason they should. If it's part of an API contract that the callee shouldn't modify something, perhaps because of an immutability assumption in the caller, then by all means add a const. If const-ness allows some kind of optimization, not so much at the compiler level but at the human/algorithmic level, go ahead. But if you're slapping a const onto a throwaway object that you're never even going to look at again before leaving scope, then stop. Are you conveying any useful intent, or just making code harder to change for no reason?