Pros and cons of "using namespace" (WAS: Consensus on when to use "using" directives)

181 views
Skip to first unread message

Kim Gräsman

unread,
Jan 6, 2012, 4:03:57 AM1/6/12
to Chromium-dev
Hi all,

I'm curious as to what experiences are driving the different opinions
on using, using namespace and explicit qualification.

Personally I'm a slob, I prefer "using namespace" in .cc files and
full qualification in headers, but I don't have any concrete facts to
make me feel comfortable, nor any to make me feel sufficiently guilty
to change my ways.

So, why is using namespace such a terrible idea?

Is the worry that naming conflicts will go unnoticed or that they will
be more difficult to resolve if they happen?

Does the amount of visible symbols impact compile time?

Is it more a matter of helping understand which specific dependencies
are there, as Darin touched on?

I would be grateful for any experiences or pointers to make it clearer
what the problem actually is.

Thanks,
- Kim

Peter Kasting

unread,
Jan 6, 2012, 12:47:22 PM1/6/12
to kim.g...@gmail.com, Chromium-dev
On Fri, Jan 6, 2012 at 1:03 AM, Kim Gräsman <kim.g...@gmail.com> wrote:
So, why is using namespace such a terrible idea?

Namespace pollution and lack of clarity.

The former is an issue when there are overlapping symbols in different namespaces (including the local scope).  The effects here are not always obvious.  Sometimes you might end up overriding some virtual function you didn't intend to, or getting name resolution that doesn't fall back as you expect.  These errors can be subtle.

The latter is an issue all the time: if I have "using namespace foo;" and then make a call to bar(), it's not clear, and not necessarily easy to determine, where bar() is defined.  Knowing that in turn might really help me understand the intent of bar().  For example, if I see a bare call to "find()" or "swap()", it would have been nice to know if these are the STL implementations, whose characteristics I'm likely familiar with, or customized versions, which I might want to examine.

Does the amount of visible symbols impact compile time?

This isn't a concern I've ever really seen raised regarding these declarations.

PK

Antoine Labour

unread,
Jan 6, 2012, 12:56:22 PM1/6/12
to kim.g...@gmail.com, Chromium-dev
On Fri, Jan 6, 2012 at 1:03 AM, Kim Gräsman <kim.g...@gmail.com> wrote:
The main issue (IMO) is that it has the potential to cause non-local conflicts.

Say you have an a.cc that includes headers from 3 other components, that use respectively the namespaces b and c, and d.

a.cc:
#include "b/bar.h"
#include "c/baz.h"
#include "d/boz.h"

using namespace b;
using namespace c;
using namespace d;

namespace a {

void Foo() {
  Bar();  // this is b::Bar()
  Baz();  // this is c::Baz()
  Boz();  // this is d::Boz()
}

}  // namespace a;


Now let's say that someone adds c::Bar() function (in c/bar.h). So far, no problem, the change goes in.
Now, say d::Boz() wants to use c::Bar(), d/boz.h will start including c/bar.h. Then suddenly a.cc stops compiling because b::Bar() conflicts with c::Bar().

Or to reiterate, by changing d to use c, it causes a conflict in a because it uses b - that's what I mean by non-local conflicts.

To solve it, one needs to either replace all calls to Bar to b::Bar in a.cc (there could be many), or explicitly promote all members of c that it uses instead of the whole namespace (there could be many as well).

It's particularly pernicious if, say, c and d are out of tree, with different maintainers (say skia and WebKit), because they will not go to chrome to find this sort of conflicts. So in that case it would fall down to the webkit gardener to change all the files like a.cc to be able to roll WebKit - they don't need that.
So we avoid the problem from the start by disallowing non-explicit promotions.

Antoine


--
Chromium Developers mailing list: chromi...@chromium.org
View archives, change email options, or unsubscribe:
   http://groups.google.com/a/chromium.org/group/chromium-dev

Scott Byer

unread,
Jan 6, 2012, 1:19:28 PM1/6/12
to kim.g...@gmail.com, Chromium-dev
On Fri, Jan 6, 2012 at 1:03 AM, Kim Gräsman <kim.g...@gmail.com> wrote:

I would be grateful for any experiences or pointers to make it clearer
what the problem actually is.



Especially pay attention to the Criticism section.
When I first got tripped up by this (so many years ago), it was definitely a big WTF? moment. 'using namespace' is an easy way to wake the snake that'll bite you.

-Scott

Kim Gräsman

unread,
Jan 6, 2012, 4:12:27 PM1/6/12
to Antoine Labour, Chromium-dev
Hi Antoine,

On Fri, Jan 6, 2012 at 18:56, Antoine Labour <pi...@google.com> wrote:
>
> The main issue (IMO) is that it has the potential to cause non-local

> conflicts. [...]

Ah, good point. I see why that's a big problem.

> It's particularly pernicious if, say, c and d are out of tree, with
> different maintainers (say skia and WebKit), because they will not go to
> chrome to find this sort of conflicts. So in that case it would fall down to
> the webkit gardener to change all the files like a.cc to be able to roll
> WebKit - they don't need that.

Right. It's sort of like the fragile base class problem, I guess.

Thanks!

- Kim

Kim Gräsman

unread,
Jan 6, 2012, 4:28:06 PM1/6/12
to scot...@chromium.org, Chromium-dev
Hi Scott,

ADL is a little funky, but can also be useful.

It doesn't need using directives or declarations, though -- you can
invoke an unqualified swap() if its arguments live in namespace std.

E.g.:

--
#include <string>

int main()
{
std::string a = "foo", b = "bar";
swap(a, b);
}
--

However, back to Peter's point, if you have one or more local swap
visible, it's not entirely clear which one it'll eventually settle on.

Thanks,
- Kim

Kim Gräsman

unread,
Jan 6, 2012, 4:30:03 PM1/6/12
to Peter Kasting, Chromium-dev
Hi Peter,

On Fri, Jan 6, 2012 at 18:47, Peter Kasting <pkas...@chromium.org> wrote:
> On Fri, Jan 6, 2012 at 1:03 AM, Kim Gräsman <kim.g...@gmail.com> wrote:
>>
>> So, why is using namespace such a terrible idea?
>
> Namespace pollution and lack of clarity.
>
> The former is an issue when there are overlapping symbols in different
> namespaces (including the local scope). The effects here are not always
> obvious. Sometimes you might end up overriding some virtual function you
> didn't intend to, or getting name resolution that doesn't fall back as you
> expect. These errors can be subtle.

I wonder if there are cases that cause a silent change in behavior,
instead of a compiler error, though. That would be terrible, but I
can't seem to come up with an example.

Maybe in multiple levels of name resolution, that might become a
problem (e.g. local scope -> dependent name -> namespaced global).

I've worried a lot about this in my day, but never seen any actual
problems. Looks like name resolution may be a scary corner.

> The latter is an issue all the time: if I have "using namespace foo;" and
> then make a call to bar(), it's not clear, and not necessarily easy to
> determine, where bar() is defined. Knowing that in turn might really help
> me understand the intent of bar().

Yes, good point. But it also depends on the code style. Sometimes it's
DSL-y (the Google Mock example earlier comes to mind), where fluency
is important, and sometimes it's more regular code where there's
clarity in understanding flow.

> For example, if I see a bare call to
> "find()" or "swap()", it would have been nice to know if these are the STL
> implementations, whose characteristics I'm likely familiar with, or
> customized versions, which I might want to examine.

True, thanks for a good example.

- Kim

Reply all
Reply to author
Forward
0 new messages