Last modified 12 years ago Last modified on 04/12/2008 07:57:04 PM

Linked from CodeStandards

During the DC3 reorganization a few issues came up that I (Russell) would like to see discussed and get at least a recommendation of best practice into the C++ standards for DC3:

Use of "using namespace" in .cc files

(See also OnUsingUsing.)

"using namespace" is already forbidden in header files for the excellent reason that it pollutes the namespace for all users of the header file.

Russell proposes to forbid or discourage it for .cc files as well because:

  • It can be very difficult to figure out where a particular symbol came from.
  • That makes refactoring harder.

Alternatives include:

  • Require the full namespace always.
  • Use "using ..." to bring in specific symbols.
  • Use an abbreviated namespace, e.g.: namespace fooBar = lsst::foo::bar;

Note that python has a very similar issue and I suggest we adopt the same rules. In that case:

  • "from import *" is analogous to "using namespace lsst::foo::bar" and is already forbidden. I found no examples of its use.
  • "from import myFunction" is analogous to "using lsst::foo::bar::myFunction
  • "import as fooBar" is analogous to "namespace fooBar = lsst::foo::bar".

RO comments:

  • Full namespace is simple and makes refactoring very easy, but it makes for very verbose code. I suspect such a rule would be widely ignored.
  • I found "using ..." worked very well. The code was kept short and it was clear where the symbols came from (at least as clear as it ever is in C++).
  • I feel that if we allow abbreviations then we should have some kind of naming guidelines. Otherwise each file may use a different abbreviation and that can be confusing. (I suggest guidelines rather than rules because I doubt rigid rules will make sensible names for all cases.)

  • My proposed guidelines:
    • use camelCase
    • concatenate the last two fields
    • abbreviate each field to at most 5 characters, using fewer if it makes a relevant word

  • For example:
    • namespace pexLog = lsst::pex:logging;
    • namespace imageTest = lsst::afw::image::testUtils;
  • The python code was a bit hard to read because of heavy use of the last option and no standardization for abbreviations.

How to handle namespaces when defining symbols

Options include:

  • Specify the namespace explicitly in the definition, e.g.:
lsst::foo::bar::myFunction(...) {...};
  • Put the definitions in a namespace block, e.g.:
namespace lsst {
namespace foo {
namespace bar {
    myFunction(...) {...};
}}} // lsst::foo::bar
  • Use an abbreviation for the namespace (a compromise), e.g.:
namespace fooBar lsst::foo::bar;

fooBar::myFunction(...) {...};

RO comments:

  • "namespace foo {..." worries me because it can add items to the namespace (they don't already have to have been defined in it). I fear this can obscure certain kinds of errors. Nonetheless KT assures me that it is safe so the fear is probably groundless.
  • My comments about full namespace and abbreviated namespace in the first item are, I think, relevant here as well.

KTL comments:

  • namespace foo { can only add items to the namespace that are visible within the same file. These cannot be used in any other file, so it's not clear to me that there are any errors that would be obscured.

Delimit include file paths with <> or ""?

This is minor and not worth a lot of discussion but we might at least suggest a preferred technique.

Right now I think everybody uses <> for includes of standard libraries and 3rd party packages (e.g. boost and VW). But some folks use "" for lsst includes (even those in other eups packages) whereas others use <> for those as well.

Are there any important reasons to suggest one or the other, or does it just come down to taste?

KTL comments:

  • <> includes search system paths before local paths and should be used for system headers. It is slightly less efficient to use it with non-system headers, which should only be searched for in -I directories and the current directory.

Note: if you add a comment using this macro please specify which section you are referring to

Comment by ktl on Sat 12 Apr 2008 02:57:04 PM CDT

Namespace abbreviations:

If we allow abbreviations, we should just pick standard abbreviations for each package for use in C++ and Python. Having "guidelines" or even strict rules that each developer has to apply makes no sense when the goal is to have everyone use the same designator.

I'm reluctant to allow abbreviations at all. Part of the logic of selecting namespace names that start with lsst is to ensure that there are no collisions. If we could ensure no collisions with abbreviated namespaces, then we should just use them and skip the lsst ones. If we cannot ensure the lack of collisions, what happens when an abbreviated namespace does collide?

Add comment