62

Someone asserted on SO today that you should never use anonymous namespaces in header files. Normally this is correct, but I seem to remember once someone told me that one of the standard libraries uses anonymous namespaces in header files to perform some sort of initialization.

Am I remembering correctly? Can someone fill in the details?

David Norman
  • 19,396
  • 12
  • 64
  • 54
  • 2
    See this discussion: [http://stackoverflow.com/questions/357404/anonynous-namespaces](http://stackoverflow.com/questions/357404/anonynous-namespaces) – John D. Cook Dec 10 '08 at 21:09
  • that's the thread where he has got that information from that anonymous namespaces in headers is bad – Johannes Schaub - litb Dec 10 '08 at 21:11
  • I can't find anything in that thread about using it in header files. Can anyone explain why this is wrong? And does it still apply in C++11? – Baruch Aug 28 '14 at 09:31

5 Answers5

33

The only situation in which a nameless namespace in header can be useful is when you want to distribute code as header files only. For example, a large standalone subset of Boost is purely headers.

The token ignore for tuples, mentioned in another answer is one example, the _1, _2 etc. bind placeholders are others.

James Hopkin
  • 13,797
  • 1
  • 42
  • 71
  • 2
    You shouldn't use anonymous namespace for this as they are all collapsed together in the final compilation unit potentially leading to namespace clashes. Instead, use a name that, by convention, means the contents are implementation details. Boost, for example, uses `detail`. – thehouse May 24 '12 at 19:26
  • 2
    @thehouse You seem to have misunderstood how Boost uses the anonymous namespaces. `ignore` and `_1`, `_2` etc. are public symbols - they don't belong in `detail`. But I agree that a detail namespace is normally the correct choice for a header library's equivalent of an anonymous namespace. – James Hopkin May 30 '12 at 10:36
  • 2
    @JamesHopkin Always happy to learn. Can you explain why _1 and _2 are in an anonymous namespace rather than just in `namespace boost`? What advantages does this confer? – thehouse May 30 '12 at 14:38
  • 18
    @thehouse It's a trick to allow a header only library to provide global objects, which would normally cause link errors. Putting an object in an anonymous namespace forces each compilation unit to create its own instance. The multiple instances don't matter in the case of _1, _2 etc. because they are stateless. Another way to do achieve the same effect is to use a static member of a template class, but then the client would have to type something like Dummy<>::_1 rather than just _1. – James Hopkin May 31 '12 at 08:15
  • @JamesHopkin Interesting, thanks. I've put global data in headers before but the users didn't need to access it directly so I could use a static member (actually a static variable in a static method IIRC). – thehouse May 31 '12 at 10:55
  • 4
    State of the art method to define `_1`, `_2`, `ignore`, etc is to use `inline` variables. – Tomilov Anatoliy Jan 15 '21 at 15:39
16

I don't see any point in putting an anonymous namespace into a header file. I've grepped the standard and the libstdc++ headers, found no anonymous namespaces apart of one in the tuple header (C++1x stuff):

  // A class (and instance) which can be used in 'tie' when an element
  // of a tuple is not required
  struct _Swallow_assign
  {
    template<class _Tp>
      _Swallow_assign&
      operator=(const _Tp&)
      { return *this; }
  };

  // TODO: Put this in some kind of shared file.
  namespace
  {
    _Swallow_assign ignore;
  }; // anonymous namespace

This is so you can do

std::tie(a, std::ignore, b) = some_tuple;

elements of the some_tuple are assigned the variables at the left side (see here), a similar technique is used for this iterator. The second element is ignored.

But as they say, it should be put into a .cpp file and the one instance should be shared by all users. They would put a declaration of it into the header like this then:

extern _Swallow_assign ignore;
Community
  • 1
  • 1
Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
8

I've seen it used to provide a default value for a variable in different translation units. But it could cause unexpected behaviour in the case of name clashes.

Example

a.hpp

namespace
{
    const char name[] = "default";
}
// This macro will hide the anonymous variable "name"
#define SET_NAME(newname) \
static const char name[] = newname;

b.cpp

#include "a.hpp"
SET_NAME("file b") // name is "file b" in this translation unit

c.cpp

#include "a.hpp"
SET_NAME("file c") // name is "file c" in this translation unit

d.cpp

#include "a.hpp"
// name is "default" in this translation unit

e.cpp

#include "a.hpp"
static const char name[] = "unintended";
// accidently hiding anonymous name
Jacqui Gurto
  • 1,496
  • 1
  • 10
  • 4
2

I really can see no positive benefit from using anonymous namespaces in headers. The confusion that can result from having the same symbol declaration mean, in essence, a different thing in the compilation units that include that header would be a guaranteed way to go prematurely and painfully bald.

Jon Trauntvein
  • 4,453
  • 6
  • 39
  • 69
0

If it's initialization, it would likely be an iostreams header (like istream, ios, etc.).

Max Lybbert
  • 19,717
  • 4
  • 46
  • 69