Implementation of a singleton class with atomic members - c++

I'm trying to implement a class to track the performances of a multithreaded code and am running into the following issue.
The tracker should have a single instance, thus the singleton pattern.
In order to count object creation and function execution accross all the threads, I thought that using atomic member would be a good idea. But I can't seem to figure out a correct implementation.
This is a minimal code of what I wand to do:
#include <atomic>
#include <iostream>
class Counter
{
public:
static Counter& instance()
{
return instance_;
};
void increment()
{
counter_++;
};
private:
Counter ()
{
std::cout << "ctor counter" << std::endl;
};
~Counter ()
{
std::cout << "counter_: " << counter_ << std::endl;
std::cout << "dtor counter" << std::endl;
}
static Counter instance_;
std::atomic<int> counter_{0};
//int counter_ = 0;
};
Counter Counter::instance_ = Counter();
int main(void)
{
Counter::instance().increment();
Counter::instance().increment();
Counter::instance().increment();
return 0;
}
If the counter_ variable is an int, it works fine, but would not be thread safe.
If it is an atomic<int>, then the compiler tells me this:
g++ foo.cc
foo.cc:34:38: error: use of deleted function 'Counter::Counter(const Counter&)'
Counter Counter::instance_ = Counter();
^
foo.cc:4:7: note: 'Counter::Counter(const Counter&)' is implicitly deleted because the default definition would be ill-formed:
class Counter
^~~~~~~
foo.cc:4:7: error: use of deleted function 'std::atomic<int>::atomic(const std::atomic<int>&)'
In file included from foo.cc:1:0:
/usr/include/c++/7/atomic:668:7: note: declared here
atomic(const atomic&) = delete;
^~~~~~
I'm not sure I quite understand the problem. Any explanation/solution would be much appreciated.
Cheers

You could simplify by having std::atomic<int> counter_{0}; simply be a static class member instead of part of each instance. (Since you're ensuring that there's only one instance the class.)
Or if you're only using your "singleton" that way returning a reference to a static object, just make all of its members static so you don't need to even get a pointer to that single instance of it in the first place. Then it can just be a glorified namespace{} with public and private static member functions. I think the only point of a "singleton" is to delay initializing it until after static initialization by using a function-scoped static with a non-constant initializer, but you're not doing that.
The actual problem is in the copy-constructor of your class, which your static initializer uses the way you've written it. It constructs a temporary Counter(); and then copies it to static instance_ variable.
You can compile as C++17 where eliding of that copy is guaranteed (works on Godbolt with g++ -std=gnu++17 with your source untouched), or you can rewrite the initializer
Counter Counter::instance_; // default construct
Counter Counter::instance_{}; // explicitly default construct
Both of those work with g++ -std=gnu++11

Related

Wondering if my shared member is working?

I have a shared_ptr I'm trying to use in two functions of a class, not sure if I have it working right. The shared object class I'm using might be broken, but it's not my repo so I'm wanting to check if it's my issue on my end.
myHeader.h
#include "otherClass.h"
namespace myheader {
class myClass : {
public:
// Constructor
myClass();
~myClass() = default;
bool incomingMessage();
private:
std::shared_ptr<randomnamespace::OtherClass> otherClass_ = std::make_shared<randomnamespace::OtherClass>();
};
};
myClass.cpp
#include "myHeader.h"
using namespace myheader;
myClass::myClass()
:
otherClass_()
{
otherClass_->setConfiguration(x);
std::cout << "Debug: Initialized";
}
bool myClass::incomingMessage() {
otherClass_->sendData();
std::cout << "Debug: Data sent";
return true;
}
I'm wondering if it seems to be shared correctly?
I've tried running this(compiling works), and the otherClass_->() calls don't work in either place. Have tried testing both individually with the other commented out, and I don't get the Debug print's after the otherClass_-> calls.
You try to initialize otherClass_ twice:
once with a default member initializer:
std::shared_ptr<randomnamespace::OtherClass> otherClass_ = std::make_shared<randomnamespace::OtherClass>();
once with a mem-initializer in the constructor:
myClass::myClass(): otherClass_()
The standard says that when this happens, the default member initializer is ignored and the member is initialized according to the mem-initializer in ctor. Here that means that you initialize otherclass_ to be an empty shared pointer...
You should remove the offending initialization in ctor:
myClass::myClass()
{
otherClass_->init();
std::cout << "Debug: Initialized";
}
Main question
myClass::myClass()
:
otherClass_()
This initializes your member (otherClass_) with nothing from the constructor.
This will override the definition of
std::shared_ptr<randomnamespace::OtherClass> otherClass_ = std::make_shared<randomnamespace::OtherClass>();
where you already have initialized it before correctly.
Solution:
Remove : otherClass_() from the constructor.
Remove the initialization from otherClass_ and use :otherClass_(std::make_shared<randomnamespace::OtherClass>()) to initialize it from the constructor.
Other notes
Remove the colon after class myClass : {.
To implement incomingMessage() you need
bool myClass::incomingMessage() {
Other than that, I don't see that you return otherClass_ anywhere or pass it as a parameter. You don't share it, you only use it. It looks like you can use a unique_ptr.

Globally called constructor of a class template that adds this pointer to static list causes error

I have a class template that keeps track of all instances of a specific instance of the class template with a list of pointers. In the constructor, I push_back(this) to add the created instance to the class. If I create an instance within main, it works fine. But if I create a global instance, the constructor causes an error. The error is from the list.push_back() and it says that the insertion iterator is out of range of the container. I have recreated the bug with minimal code.
Header file
#ifndef HEADER_H
#define HEADER_H
#include <iostream>
#include <list>
template<typename T>
class A
{
public:
static std::list<A<T>*> l;
A( T t ) : val( t ) { l.push_back( this ); }
~A() { l.remove( this ); }
T val;
void print() { std::cout << val; }
};
template<typename T>
std::list<A<T>*> A<T>::l;
#endif
Source file
#include "Header.h"
A<int> temp( 0 );
void main()
{
temp.print();
char c;
std::cin >> c;
}
I'm guessing it has something to do with the constructor call order, but does anyone know how to fix this?
Static members of template class specializations have unordered dynamic initialization, meaning that there is no guarantee in what order they will be initialized relative to other dynamic initialization.
If A<int>::l is initialized after temp, then initialization of temp will try to access A<int>::l before its lifetime began, causing undefined behavior.
The usual solution to this is to put the static variable in a static function and call that instead. Local static variables are initialized when execution reaches their declaration the first time, so it is always properly ordered.
template<typename T>
class A
{
public:
static auto& l() {
static std::list<A<T>*> instance;
return instance;
}
A( T t ) : val( t ) { l().push_back( this ); }
~A() { l().remove( this ); }
T val;
void print() { std::cout << val; }
};
Non-const global variables should however be avoided as much as possible in the first place. They usually make reasoning about the code more complex and have problems such as initialization order here.
I don't know what the purpose of the instance list here is, but it has similar issues and should probably be avoided if possible. Additionally it will have quite bad performance, especially if you have many instances of A<T> around, because l.remove( this ); will take linear time in the number of elements in the list. Consider using std::set or std::unordered_set instead of std::list.
Additional notes:
The return type of main must be int in C++. void as return type is a non-standard extension of some compilers.
Your class is violating the rule of 0/3/5. You need to define copy (and move) constructor and assignment operator with correct semantics, otherwise your instance list will not contain all instances when your class is copied.
You also might want to save const A<T>* instead of A<T>* in the list. The latter is dangerous. If you ever declare a variable of type const A<T>, then the pointer you save in the list will still be non-const. If you then use the pointer from the list to modify the object, you will not be warned that you are trying to modify a const object (which causes undefined behavior).
Using a block scoped static variable (local static variable in a function / static function) is very good approach because initialization of class template static data members and other static/thread-local variables are indeterminately sequenced with respect to each other and this causing problem of accessing a variable which is not yet initialized. read more about it, at Static non-local initialization
But this approach will not allow to use A<T>::l, because then, std::list<A<T>*> l variable is not static member of class A<T>, It means if static member of a class can't be avoided due to some requirements then this unordered initialization problem has to be resolved.
Now unordered initialization can be converted into ordered initialization by using explicit template initialization, as follows,
template class A<int>; //explicit template initialization
A<int> temp(1);
It will make sure that std::list<A<T>*> l get initialized before temp object initialization. This explicit template initialization has to be done in each translation unit where you want to create non-local variable of A<T>. Let's look at the code,
Header file is similar (no change),
Source file
#include "Header.h"
template class A<int>; //explicit template initialization
A<int> temp(0);
int main(int , char *[]){
std::cout<< "temp.val = ";
temp.print();
std::cout<< '\n';
}

Deferring C++ static object construction - GCC on Linux

Imagine I have a C++ class called MyClass.
Imagine that I have no access to the source code of MyClass ... it is contained in a library and I am supplied only the library and the header file for MyClass.
Imagine that the class itself requires environment pre-configuration ... for example ... before the constructor of the class can be called, I need to do some setup. The class is normally meant to be used as follows:
void func() {
doGlobalSetup();
MyClass myInstance(1,2,3);
myInstance.doSomething();
...
}
Now I have the situation where we need to create a global instance of the class such as:
MyClass myInstance(1,2,3);
int main(int argc, char *argv[]) {
doGlobalSetup();
myInstance.doSomething();
}
The problem is that in this story, the instance of MyClass is created before the call to doGlobalSetup(). It is instantiated before main() is called. What I want to do is either defer the creation of myInstance() till later or be able to run doGlobalSetup() somehow before the instantiation of the class.
This is a simplification of the actual story ... so let us assume:
I can't change the internals of MyClass.
There must be an instance variable called myInstance of type MyClass (I can't change the logic to MyClass *pMyInstance).
Many thanks for reading.
Since you've constrained the problem such that new cannot be used, you should be able to create the object as always and copy it to the global instance. For example:
MyClass createMyClass()
{
doGlobalSetup();
return MyClass(1, 2, 3);
}
MyClass myInstance = createMyClass();
int main()
{
myInstance.doSomething();
return 0;
}
Does it suit your needs?
namespace
{
int doStaticGlobalSetup()
{
doGlobalSetup();
return 0;
}
}
MyClass myInstance(doStaticGlobalSetup() + 1,2,3);
int main() {
myInstance.doSomething();
return 0;
}
If you absolutely have to defer any constructor calls until after global initialization is done, and want to be sure that no static order initialization fiasco happens, there is a way: make myInstance a reference to uninitialized block of memory and create object in it using placement new after global initializaton.
#include <iostream>
#include <type_traits>
struct foo
{
foo() { std::cout << "created\n"; }
void meow() { std::cout << "used\n"; }
~foo() { std::cout << "destroyed\n"; }
};
void doGlobalSetup() { std::cout << "Global setup\n"; }
//Actual implementation
namespace {
typename std::aligned_storage<sizeof(foo), alignof(foo)>::type bar;
}
foo& instance = reinterpret_cast<foo&>(bar);
//Allows automatic creation and destruction
struct initializer
{
initializer()
{
if (!initialized)
new (&instance) foo();
initialized = true;
}
~initializer()
{
if(initialized)
instance.~foo();
initialized = false;
}
private:
static bool initialized;
};
bool initializer::initialized = false;
int main()
{
doGlobalSetup();
initializer _;
instance.meow();
}
Use a static variable inside a function.
MyClass &myInstance() {
doGlobalSetup();
static MyClass myInstance(1,2,3);
return myInstance;
}
void func() {
myInstance().doSomething();
}
You probably already got the answer you wanted. But just to cover the whole spectrum: if, for some reason, you want to make sure that other places in the code don't accidentally construct MyClass independently of your global variable--and before the global setup has been made--you need to solve this with linking.
If you're on Linux, you can LD_PRELOAD a shared-object containing just the symbol for MyClass's constructor. In it, you declare the setup function accordingly, and let the dynamic linker do the job for you. Then, inside the constructor, you call the setup function, and then do a dlsym("...", RTLD_NEXT) to get the pointer to the original constructor, and you call it, passing it the arguments you got. Of course, you maintain and check a static flag for whether setup has already been performed.
Again, this is probably overkill for you, but I'm posting it just in case someone needs (and is able to use) this kind of solution.
P.S. This is what you get when you rely on global state! :)
First, bear in mind that given a library init function like doGlobalSetup there is a distinct nonzero chance the library will just not work if you create a global instance.
Otherwise it's super easy to create an initializer with the comma operator:
bool do_my_setup = (doGlobalSetup(), true);
MyClass myInstance(1,2,3);
Within the GCC compiler environment there is a function attribute capability called constructor. This allows us to flag a function definition with the ability for it to be automatically invoked before main is called and, most importantly before any class constructors are invoked.
Referring back to the original problem definition ... if the doGlobalSetup() function is modified from:
void doGlobalSetup() { ... }
to
__attribute__((constructor)) void doGlobalSetup() { ... }
then its invocation will occur before main is called and also before any static class instance constructors are called. The explicit call to this function would also be removed from main() as its work has been performed implicitly.

C++ how safe are self registering classes?

Coming from this thread I implemented a similar system in c++ to the chosen solution there.
My problem now is that it is stated there by the user Daniel James that this solution might not work with every compiler (I'm using gcc currently) and is not defined in the c++ standard.
Suppose I have an abstract base-class for the interface and a factory-class as a singleton that stores pointers to a function that constructs the specific classes derived from that interface.
then I have a helper class that looks roughly like this:
base.hpp
...
class implRegistrator {
public:
implRegistrator(constructPointer) {
factory::registerImpl(constructPointer);
};
}
And an implementation that (through a macro) creates an object of this class to register itself:
impl1.cpp
...
implRegistrator* impl1 = new implRegistrator(getConstructPointer());
How compatible to the C++ standard is this solution? Is it safe to assume that the class instantiation ind impl1.cpp will even happen, since nothing from the main program will actually explicitly call it at compile-time?
Thanks in advance for any answers.
So after looking a bit further into the standard at the position where Angew pointed me before, I noticed footnote 34 in [basic.start.init]§4 of the standard that states:
A non-local variable with static storage duration having initialization with side-effects must be initialized even if it is not odr-used (3.2, 3.7.1).
And that actually addresses the problem which is mentioned here. The self registering class is not odr-used and modifies the state of the factory object, thus having an initialization with side-effects.
So per this footnote it is actually safe to do a self registration like the one mentioned by me and Skizz.
Edit: As Matt McNabb mentioned, I shouldn't have relied on the footnote. So here is the part of the specification that the footnote refers to: [Basic.stc.static] §2
If a variable with static storage duration has initialization or a destructor with side effects, it shall not be eliminated even if it appears to be unused, except that a class object or its copy/move may be eliminated as specified in 12.8.
From a standards perspective you can be sure if that translation unit is included in the build. However, as of old there was a problem with Visual C++ static libraries. To be safe I'd use explicit module initializations at the top level of control, or the trick employed by original iostreams implementation, where the header file causes a small internal linkage thing to be initialized, which in turn causes module initialization if not already done.
Oh well I have a question: does anyone remember "Hoare envelopes" module initialization feature, and perhaps direct me to some material? I remember re-searching some years ago, and only hitting my own earlier questions. Frustrating.
No, it is in general not guaranteed that the vairable impl1 will ever be initialised. All the standard says is that a namespace-scope variable is guaranteed to be initialised before the first function defined in the same translation unit (the same .cpp file) is called, or a variable from that translation unit is first used.
The letter of the law is C++11 [basic.start.init]§4:
It is implementation-defined whether the dynamic initialization of a non-local variable with static storage duration is done before the first statement of main. If the initialization is deferred to some point in time after the first statement of main, it shall occur before the first odr-use (3.2) of any function or variable defined in the same translation unit as the variable to be initialized.
So if your impl1.cpp contains the registration variables only, they are not guaranteed to ever be initialised. However, if it contains any functions which will get exectued when your program runs (or a variable referenced from outside), you're guaranteed to have them initialised before any such function is run or variable is referenced.
I see two problems with the code. Firstly, you're using dynamic allocation and secondly, you're using function pointers. Here is my solution:-
#include <iostream>
#include <string>
#include <map>
class FactoryBase
{
protected:
FactoryBase (const std::string &name)
{
m_factory_items [name] = this;
}
public:
virtual ~FactoryBase ()
{
}
template <class T> static T *Create ()
{
return static_cast <T *> (m_factory_items [T::Name]->Create ());
}
private:
virtual void *Create () = 0;
private:
static std::map <const std::string, FactoryBase *>
m_factory_items;
};
std::map <const std::string, FactoryBase *>
FactoryBase::m_factory_items;
template <class T>
class FactoryItem : public FactoryBase
{
public:
FactoryItem () :
FactoryBase (T::Name)
{
std::cout << "Registering class: " << T::Name << std::endl;
}
virtual ~FactoryItem ()
{
}
private:
virtual void *Create ()
{
return new T;
}
};
class A
{
public:
A ()
{
std::cout << "Creating A" << std::endl;
}
virtual ~A ()
{
std::cout << "Deleting A" << std::endl;
}
static const std::string
Name;
private:
static FactoryItem <A>
m_registration;
};
const std::string
A::Name ("A");
FactoryItem <A>
A::m_registration;
class B
{
public:
B ()
{
std::cout << "Creating B" << std::endl;
}
virtual ~B ()
{
std::cout << "Deleting B" << std::endl;
}
static const std::string
Name;
private:
static FactoryItem <B>
m_registration;
};
const std::string
B::Name ("B");
FactoryItem <B>
B::m_registration;
int main (int argc, char *argv [])
{
A
*item_a = FactoryBase::Create <A> ();
B
*item_b = FactoryBase::Create <B> ();
delete item_a;
delete item_b;
}
There's no error checking in the Create function, but I'll leave that as an exercise for the reader.
Here's an implementation of this factory pattern that tackles this specific issue.
It makes sure the factory singleton implementation is the one that calls the registrar methods on construction. Which means that, if the factory is used the registration will happen.

Does C++ compiler automatically sets my function as static?

Here's my question with sample code.
In the case a class function never uses instance related data or never references this, could the compiler decide this function is kind of static ?
As an example see this code (with description below) :
class Dummy
{
public:
Dummy()
{
std::cout << "Dummy()" << std::endl;
mInstance = this;
}
~Dummy()
{
std::cout << "~Dummy()" << std::endl;
mInstance = nullptr;
}
static Dummy& instance()
{
std::cout << "static Dummy& instance()" << std::endl;
return *mInstance;
}
void foo()
{
std::cout << "bar" << std::endl;
}
private:
int mData;
static Dummy* mInstance;
};
Dummy* Dummy::mInstance = nullptr;
At construction, my Dummy class references it's instance in a static variable called mInstance using a pointer.
mInstance is available through the static function instance().
foo() is not a static function. Hence I need and instance to call it.
mInstance is initialized to nullptr.
That case if my main only does :
Dummy::instance().foo();
I should get a seg fault. Because instance() would de-reference a nullptr.
Instead the program runs and the output will be :
bar
...And only this line so it does not seem to call neither the constructor nor the destructor.
Yet if my foo() function is :
void foo()
{
mData = 5;
std::cout << "bar" << std::endl;
}
Here a seg fault occurs.
I tend to guess as foo() actually did not reference anything proper to the instance, the compiler guessed it was a static and compiled this way.
But it does not seem to be logical as instance() function returns a reference to an instance and even if the foo() is static, foo() should not be callable...
As an other example, without the mData = 5 instruction, if my main is :
Dummy& vDummy = Dummy::instance();
std::cout << &vDummy << std::endl;
vDummy.foo();
The output is :
statci Dummy& instance()
0
bar
I don't really understand the way things are done here.... :/
You can think of member functions (non static) as functions with a hidden parameter that is a pointer to your object. So your void foo() could be considered as void foo(Dummy* d). And since you never use that pointer to Dummy, it does not matter if you pass a NULL pointer to it.
Hope this makes sense :)
For further reading about this type of undefined behaviour:
When does invoking a member function on a null instance result in undefined behavior?
The reason for this behaviour is that 'foo()' isn't virtual, so the object it's being called on is only used for type information at compile time. At runtime the fact that it's null has no effect, unless you used 'this' inside 'foo()', when you would get a nasty surprise, as you did when you tried to set a member variable, which uses 'this' implicitly.