mikejsavage.co.uk • About • Archive • RSS • Thanks for blocking ads! Blocking ads owns: AdGuard for Safari / uBlock Origin for everything else
namespace
in C++ is an odd one. Even anti-C++ people do not seem to
complain about it, and it's not obvious exactly why it's bad. It's taken
me some years of programming in C++ to come to that realisation myself.
The problem with namespace
is that it brings no upsides and causes
problems that are very annoying and somewhat time consuming to debug.
You write code that looks fine, get some linker error about "can't find
function f" when you literally just wrote function f, and unless you
know know from experience that it's going to be a namespace bug (you
learn after a few times but these errors are so infrequent that can take
many years) you can waste a lot of time going down dead ends.
Even if you suspect it's a namespace bug it can be hard to figure out
exactly what the problem is because code affected by a namespace is
mostly indistinguishable from code that isn't. You generally wrap the
whole file in namespace Company { }
, and C++ people don't indent
inside namespace blocks, so unless the start of the namespace block is
on your screen you have no idea if a given function is namespaced or
not. You just assume that it is because that's how it is 99% of the
time.
To give a concrete example of a namespace problem, here's the one that prompted me to write this post:
A
in the global namespaceA
is all private, so the whole header is in the company namespaceA::b
to be a free functionA::
,
added it to the header)A is not in the company namespace and I left the new function in amongst A's method definitions, so my new function was not in the company namespace either. The whole header is in the global namespace, so there was a mismatch, and it took a lot of WTFing to figure out what the problem was.
Some people may disagree that namespace
has no upsides, I know the
point is to prevent naming collisions, but those never happen. Obviously
when writing new code you can namespace the function name
(renderer_init
vs Renderer::init
), which leaves third party
libraries. In my experience libs just don't have naming collisions, so
unless you're deep in dependency hell it's not a problem, and namespace
is not the right solution in that case.
We could help the situation by indenting inside namespace blocks (like C# people do), or by having better compiler errors by suggesting near matches, but honestly the simplest solution is to just not use namespaces.