mt_ mt_ - 1 month ago 6
C++ Question

Global variable in namespace - Values differ in threads

Consider the following szenario:


  • 2 different network-ports via
    boost::asio
    each in its own thread

  • 1 port is receiving and processing data -
    class DataConnection
    wrapped in a
    std::thread

  • 1 port is for sending statistics
    class StatConnection
    also wrapped in a
    std::thread



For counting connections (and other small data pieces) my idea was to use a
static
variable inside a
namespace
like:

#include <atomic>

namespace app {
namespace status {
static std::atomic<long> counter = 0;
}
}


This works fine for the
DataConnection
class. Here I increment
counter
in the c'tor and see the value increments.

But
counter
in my
StatConnection
class is always
0


Why can this happen?

I've tried some alternatives:


  • exchanging
    std::atomic<long>
    for
    static volatile long
    : Did not made a difference.

  • using the namespace without
    static
    keyword.



Then I got linker errors:

multiple definition of `app::status::searchtime'
./src/status/Status.o:/[...]/include/status/Status.hpp:16: first defined here
[...]


So why is the value of
count
different between threads?

Answer

static in namespace scope introduces internal linkage, so each translation unit will have its own copy of counter – quite the opposite of what you actually want!

Use extern instead, in the header:

//foo.h:
#include <atomic>

namespace app {
    namespace status {
        extern std::atomic<long> counter;
    }
}

Then define the variable in one translation unit:

//foo.cpp:
#include "foo.h"

namespace app {
    namespace status {
        std::atomic<long> counter{0L};
    }
}
Comments