Sign in to follow this  
staticVoid2

'using namespace' or 'namespace::'?

Recommended Posts

I've seen a lot of code that does:

using namespace ...;

and then uses whatever classes, functions, globals that are in that namespace. on the other hand, I have also seen a lot of code that does:

namespace::object

but what is considered better practice? I know that if you are wanting to use two namespaces that have the same object names in them, then the second way would be the way to go, but it can also make your code unreadable and messy when you prefix everthing with NameSpace:: especially when you have nested namespaces.

Share this post


Link to post
Share on other sites
The rule is: don't put "using" directives in a header file.

In a source file, use whatever is cleaner. I found though that once I started writing the fully qualified names in the header, I started to use it almost universally.

For nested namespaces, I believe you can do the following:

namespace shortcut = silly::number::of::nested::namespaces;

// use shortcut::foo

Share this post


Link to post
Share on other sites
Our local style is to use "namespace::" in headers, to avoid making namespaces useless, and "using namespace" in cpp files, until there is a problem. Namespace clashes seem to be rare enough that this policy works very well for us.

Share this post


Link to post
Share on other sites
Is it better to refer to my friend Jerry as "my friend Jerry", or to make it clear from context that all the people I'm talking about are my friends, and then just call him by name?

It depends.

If one were clearly preferable to the other, you wouldn't be able to do both.

The reason we use (that we *have*) namespaces, instead of tagging things manually with prefixes (thus foo::bar instead of foo_bar), is that we can omit the prefixes when there would be no ambiguity. Writing it every time makes things ugly, but you have to consider whether going too far the other way would make things difficult either for the compiler (by causing name collisions) or the reader (by making it hard to figure out where names come from).

Share this post


Link to post
Share on other sites
Another point you might want to look out for (which may or may not be applicable to you). If you stick to the notion that 'using namespace' is ok in .cpp files but not in .h files, then this logic can be faulty if you are using a unity build system (where you don't compile the individual .cpp files, but include each .cpp file in one .cpp file which is then compiled).

Share this post


Link to post
Share on other sites
Quote:
Original post by _moagstar_
Another point you might want to look out for (which may or may not be applicable to you). If you stick to the notion that 'using namespace' is ok in .cpp files but not in .h files, then this logic can be faulty if you are using a unity build system (where you don't compile the individual .cpp files, but include each .cpp file in one .cpp file which is then compiled).


Why on earth would you do that do yourself?

Share this post


Link to post
Share on other sites
Quote:
Original post by ChaosEngine
Quote:
Original post by _moagstar_
Another point you might want to look out for (which may or may not be applicable to you). If you stick to the notion that 'using namespace' is ok in .cpp files but not in .h files, then this logic can be faulty if you are using a unity build system (where you don't compile the individual .cpp files, but include each .cpp file in one .cpp file which is then compiled).


Why on earth would you do that do yourself?


The single most compelling argument for monolithic .cpp files (and the reason we use something similar at work) is build time improvements. By building your entire project in a single compilation unit, you can insure that header files are included only once and therefor you are not building the same code in many compilation units.

This technique cut full build times for me from 45-60 minutes to around 10. The tradeoff is slightly increased incremental build times, but it's well worth it (for me, YMMV).

Share this post


Link to post
Share on other sites
Our friend Cylon tells us (##c++ @ freenode):

00:34 < exDM69_> !using namespace
00:34 < nolyc> The use of using-directives (e.g. `using namespace std;') is
discouraged, because: (1) in the case of namespace std, it
potentially brings hundreds of names from the entire standard
library into scope, and (2) their use obscures the origins of
unqualified names in your code. Use explicit qualification (e.g.
`std::cout') and/or using-declarations (e.g. `using std::cout;')
instead.




Quote:
Original post by Zahlman
The reason we use (that we *have*) namespaces, instead of tagging things manually with prefixes (thus foo::bar instead of foo_bar), is that we can omit the prefixes when there would be no ambiguity. Writing it every time makes things ugly, but you have to consider whether going too far the other way would make things difficult either for the compiler (by causing name collisions) or the reader (by making it hard to figure out where names come from).


Namespaces are a bit more than that (albeit nowhere near a real module system). Combined with Koenig lookup (search for function in the namespaces of their arguments) and some generic programming, namespaces have significant advantages over a plain old naming prefix. Good examples that use this are std::min and std::abs. (btw, you should always do using std::min; min(x); instead of std::min(x) if the code is in a template and x is of unknown type).

My guideline is as follows: I almost always do std::, quite often I do using boost::bind and sometimes even using namespace boost::lambda and I always do namespace po = boost::program_options when I encounter annoyingly long namespace names. I always try to stick with the innermost scope, and very seldom do anything outside a function-bound scope. I usually name my own namespaces with 3-5 letter names.

-Riku

Share this post


Link to post
Share on other sites
Quote:
Original post by Driv3MeFar
Quote:
Original post by ChaosEngine
Quote:
Original post by _moagstar_
Another point you might want to look out for (which may or may not be applicable to you). If you stick to the notion that 'using namespace' is ok in .cpp files but not in .h files, then this logic can be faulty if you are using a unity build system (where you don't compile the individual .cpp files, but include each .cpp file in one .cpp file which is then compiled).


Why on earth would you do that do yourself?


The single most compelling argument for monolithic .cpp files (and the reason we use something similar at work) is build time improvements. By building your entire project in a single compilation unit, you can insure that header files are included only once and therefor you are not building the same code in many compilation units.

This technique cut full build times for me from 45-60 minutes to around 10. The tradeoff is slightly increased incremental build times, but it's well worth it (for me, YMMV).


"Slightly" increased incremental build times? In this approach every time you make any change to a single line of code, you have to rebuild your entire project! Admittedly that rebuild will be faster, but precompiled header files are a much more elegant solution to that problem.

As you said, this works for you, but I really don't see how. I would generally only rebuild for a release (or if there's some weird compilation issue), but when debugging, I might build 10 times an hour. The tradeoff simply wouldn't be worth it for me (but as you said, YMMV).

Share this post


Link to post
Share on other sites
Quote:
Original post by ChaosEngine
"Slightly" increased incremental build times? In this approach every time you make any change to a single line of code, you have to rebuild your entire project! Admittedly that rebuild will be faster, but precompiled header files are a much more elegant solution to that problem.


That's why you have your code base organized into manageably sized projects. When we changed the way our builds worked, my incremental build times went from 2 minutes to maybe 3, as long as my changes were all local to a single project (which they usually are). It is by no means painful, especially compared to sitting around for an hour waiting for a full build to finish (say, after synching to head in version control, or modifying a core file, or bumping a version number).

In cases where I have changes spanning 2 or 3 projects, build times when from ~15 minutes to 4 or 5. As long as you have things organized intelligently, there is very little downside. There's also nothing that excludes this approach from being used in conjunction with PCHs.

Our approach at work is to combine all the source files in a project into uber-cpp's such that no more than 200 (or something like that) cpp files are included in a single uber-cpp. This generally leads to 2-3 uber files per project, meaning an incrmental build is more along the lines of building 1/3 or so of any given project. This is not a long process, and is by far a net savings.

But as I said, this is just how we do things with our project layout. YMMV.

Share this post


Link to post
Share on other sites
If you're working at home then I understand a unity build system, but in a professional environment (i.e. your company has money budgeted for things like this) wouldn't it worth shelling out the cash for a real build system like IncrediBuild?

Share this post


Link to post
Share on other sites
I use namespace::

if there is a specific area of code where a certain namespace is to be used repeatedly, then it may make sense to use a using keyword within a smaller codeblock, just for that section
  do this;
do that;
{using namespace draw;
color(red);
location(10,20);
sprite(enemy);
}
do more stuff;
instead of..
  do this;
do that;
draw::color(red);
draw::location(10,20);
draw::sprite(enemy);
do more stuff;
That is not a terribly good example, & I apologize..

But as a rule of thumb - if I can fully foresee the area for which the using keyword is to be applied, then I consider it "safe" usage. but if it extends beyond a specialised area (like being used globally within a source or header file) then I will avoid it

Share this post


Link to post
Share on other sites
Quote:
Original post by ChaosEngine
Quote:
Original post by _moagstar_
Another point you might want to look out for (which may or may not be applicable to you). If you stick to the notion that 'using namespace' is ok in .cpp files but not in .h files, then this logic can be faulty if you are using a unity build system (where you don't compile the individual .cpp files, but include each .cpp file in one .cpp file which is then compiled).


Why on earth would you do that do yourself?


I'm not advocating unity build systems (or criticising them - thats a completely different conversation). I just thought it was worth mentioning as it's relevant to this discussion, when we tested using a unity build system at work, it made the namespaces virtually useless because there were loads of places where using namespace had been used in the .cpp files.

Share this post


Link to post
Share on other sites
Quote:
Original post by ChaosEngine
Quote:
Original post by _moagstar_
Another point you might want to look out for (which may or may not be applicable to you). If you stick to the notion that 'using namespace' is ok in .cpp files but not in .h files, then this logic can be faulty if you are using a unity build system (where you don't compile the individual .cpp files, but include each .cpp file in one .cpp file which is then compiled).


Why on earth would you do that do yourself?


Two more reasons:

  • Helping the compiler with whole-program-optimisation, e.g. IPA or function inlining and more (depends on the compiler you use)

  • Source code level distribution of libraries without fearing ABI- and compiler specific .lib/.so/.etc-issues. Sqlite has such a "library", called the Amalgam, which is the most easy and convenient way to bind to sqlite statically, and of course this is the most easy way to distribute your library.
    Of course, you can then whole-program-optimise with such libraries inline (again, compiler dependent)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this