Boost logo

Boost Users :

Subject: [Boost-users] globals best-practices (avoiding multiple definitions)
From: craigp (craigp98072_at_[hidden])
Date: 2008-09-06 06:49:59


Hi -

I'm trying to understand the best practice for handling globals (within a namespace), and in particular, avoiding multiple definitions (whether multiple "private" copies or collisions causing a linker error).

For namespace globals, if I do something like this (in a header file):

  namespace log_categories
  {
    static log_t server(log_t::category("http.server.server"));
  }

I'd guess that each translation unit (TU) would get its own copy of log_categories::server (or maybe some compilers give a multiple-definition link error, while others would just make multiple private copies?). OTOH, if I only declared the variable and put the definition in a c++ file, there would only be a single copy.

For class static members, you cannot initialize the members "in-line" (unless it's an integral constant).

One interesting "work-around" I saw in asio/error.hpp was this:

namespace boost { ...

  static const boost::system::error_category& system_category
    = boost::asio::error::get_system_category();
...

This way, there might be multiple copies but they will all be references to the same underlying object.

For the case of class template static members, I found this example in complex.hpp:

namespace boost { namespace numeric
{
    namespace detail
    {
        template<typename T>
        struct one_complex
        {
            static std::complex<T> const value;
        };

        template<typename T>
        std::complex<T> const one_complex<T>::value
          = std::complex<T>(numeric::one<T>::value, numeric::one<T>::value);
    }
...

Is it guaranteed that there will only be one instance of one_complex<T>::value for each T, even if this header file is included in multiple TU's? In this case it doesn't matter (it's a constant), but in other cases I need to ensure that it's a true singleton.

Is there a good resource on best-practices for this? I've been bitten by the "multiple-definition" bug in several guises before (eg: in windows when there were multiple libraries linking to the same dll). I googled, and saw suggestions from, say, DEC (http://www.helsinki.fi/atk/unix/dec_manuals/cxx_6.0/cxx570_ug_004.html), which were to put template definitions in separate "template definition files." I take it complex.hpp is best-practice (standards-compatible, portable, etc - at least with certain options set on a particular vendor's compiler, say, automatic template instantiation)?

Handling declarations vs definitions of template specializations seems even more fraught, but thankfully I don't have to worry about that for now (plus, it would certainly simplify things to always keep both template decls and defs in the same header file).

thanks,
--craig

      


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net