Static inline members initialization order - c++

A well known problem in C++ is the static initialization order fiasco. Is it still considered a problem when one use C++17 static inline members?
Here an example where a static inline member is used in two different translation units (a.cpp and b.cpp) as an initializer for two non-inline static members:
counter.hh
#pragma once
#include <vector>
#include <fstream>
class Counter
{
public:
Counter() { std::ofstream os("o.txt", std::ofstream::app); os << "Counter created" << std::endl; }
~Counter() { std::ofstream os("o.txt", std::ofstream::app); os << "Counter destroyed" << std::endl; }
void add_instance()
{
++m_instances;
std::ofstream os("o.txt", std::ofstream::app); os << "Counter increased: " << m_instances << std::endl;
}
void remove_instance()
{
--m_instances;
std::ofstream os("o.txt", std::ofstream::app); os << "Counter decreased: " << m_instances << std::endl;
}
private:
int m_instances = 0;
};
class Object
{
public:
Object(Counter & counter) : m_counter(counter)
{
m_counter.add_instance();
std::ofstream os("o.txt", std::ofstream::app); os << "Object created" << std::endl;
}
~Object()
{
m_counter.remove_instance();
std::ofstream os("o.txt", std::ofstream::app); os << "Object destroyed" << std::endl;
}
private:
Counter & m_counter;
};
struct C
{
static inline Counter static_counter{};
};
a.hh
#pragma once
#include "counter.hh"
struct A
{
static Object static_a; //not inline
};
a.cpp
#include "a.hh"
Object A::static_a{C::static_counter};
b.hh
#pragma once
#include "counter.hh"
struct B
{
static Object static_b; //not inline
};
b.cpp
#include "b.hh"
Object B::static_b{C::static_counter};
main.cpp
#include "a.hh"
#include "b.hh"
int main() { }
output (with MSVC 16.1.2)
Counter created
Counter increased: 1
Object created
Counter increased: 2
Object created
Counter decreased: 1
Object destroyed
Counter decreased: 0
Object destroyed
Counter destroyed
I think that, with regard to the initialization, this practice is safe because the C++17 standard ensures that static inline members are: (1) always initialized before any use and (2) initialized only once across multiple translation units.
But I'd like to know if there are any hidden downsides in this pattern, for example related to the order of destruction of each variable across different TUs. Is it well-defined that both static_a and static_b are always destroyed before static_counter?

Yes, this is fine, since in every translation unit static_counter is defined before static_a/static_b. Destruction order is not guaranteed to be the reverse (given threads, this is meaningless anyway), but the reverse of each guarantee holds, so that works too.

Related

Global static variable initialised with a call to static class function in c++

Not sure how correctly formulate the question but here is the problem.
I have a static lib where I have the following class in a.h:
#pragma once
#include <vector>
class A{
public:
void Run() {
data_.push_back(10);
std::cout << "size: " << data_.size() << std::endl;
}
private:
static std::vector<int> data_;
};
a.cpp is as follows:
#include "a.h"
std::vector<int> A::data_;
And I have another class in b.h:
#pragma once
#include <string>
class B
{
public:
static std::string Get();
};
And b.cpp:
#include "b.h"
#include "a.h"
std::string B::Get()
{
static A a;
a.Run();
return "foo";
}
Now my main app which is using the above static lib is as follows:
#include <iostream>
#include "a.h"
#include "b.h"
static std::string var1= B::Get();
int main(int argc, char** argv)
{
A a;
a.Run();
}
Trying to understand why the output is:
size: 1
size: 1
There should be a single instance of each static data member for the entire class, so there should be a single call to A::data_ constructor.
Am I hitting "static initialization order fiasco"? I.e. data_ is not initialised before I use it, but then I should be getting the crash?
And now lets imagine my data_ holds dynamically initialised items (something none POD). How will it be destructed if at the end data_ holds one item, although I've inserted 2?
And that's what actually is happening in my real life code (it sometimes crashes during destruction of data_).
Getting rid of global static ( static std::string var1= B::Get(); ) solves the problem, but I still want to understand the under the hood problem.
The described case can be reproduced in VS2015 (the real life case is reproducible in gcc 6.2 )
Am I hitting "static initialization order fiasco"?
Most likely.
You can remove the problem by making the static data of a class available via a function call. E.g.
class A{
public:
void Run() {
getData().push_back(10);
std::cout << "size: " << getData().size() << std::endl;
}
private:
static std::vector<int>& getData();
};
std::vector<int>& A::getData()
{
static std::vector<int> data;
return data;
}
When you do that, data will be initialized when A::getData() is called the first time. It removes the static initialization order issue completely.

How to access data type of a class declared in one class into another class (both in different translation unit)?

I have 5 files. (1. A.hpp, A.cpp : 2. B.hpp, B.cpp : 3 main.cpp)
// A.hpp
#ifndef MY_CLASS_A
#define MY_CLASS_A
#include <iostream>
class B; // forward declaration so that I could do B * b;
struct s {
int x;
double y;
};
class A{
s my_struct;
int size;
B * b;
public:
A(int, double, int);
void f1(s);
void f2(); // this function calls B's f1 function
s get_struct();
int get_size();
void print();
};
#endif
Then I have its implementation as
// A.cpp
#include "A.hpp"
#include "B.hpp"
A::A(int x_, double y_, int size_):my_struct({x_, y_}), size(size_){}
void A::f1(s s_){
// do stuff
s_.x = 5;
s_.y = 51.99;
}
void A::f2(){
int val;
// Here I am calling B's f1 function
val = b->f1(my_struct);
}
s A::get_struct(){
return my_struct;
}
int A::get_size(){
return size;
}
void A::print(){
std::cout << " ----- " << std::endl;
std::cout << "x = " << my_struct.x << std::endl;
std::cout << "y = " << my_struct.y << std::endl;
std::cout << "size = " << size << std::endl;
std::cout << " ----- " << std::endl;
}
Then I have B
//B.hpp
#ifndef MY_CLASS_B
#define MY_CASS_B
#include "A.hpp" // I placed here A.hpp because I am
// trying to use A's struct type
class A;
class B{
public:
int f1(s); // A's struct use here to get struct by value
};
#endif
and its implementation as
// B.cpp
#include "B.hpp"
// used A's struct here again
int B::f1(s my_struct){
std::cout << "*****" << std::endl;
std::cout << my_struct.x << std::endl;
std::cout << my_struct.y << std::endl;
std::cout << "*****" << std::endl;
}
finally main as
// main.cpp
// As per comment I should place #include "A.hpp" here
#include "A.cpp"
int main(){
A a(4,9.9, 5);
a.print();
return 0;
}
My main question is how can I access the struct declared in class A into class B?
I have tried to use forward declaration by failed miserably.
Open your C++ book to the chapter on pointers and references, and read that chapter again.
"The struct declared in class A" is my_struct, which is a private class member.
To have it accessible elsewhere, you need to pass it by reference.
int B::f1(const s &my_struct){
std::cout << "*****" << std::endl;
std::cout << my_struct.x << std::endl;
std::cout << my_struct.y << std::endl;
std::cout << "*****" << std::endl;
}
Now, when you invoke this from A:
val = b->f1(my_struct);
This will now pass a reference to the my_struct member, instead of making a copy of it.
Note that the parameter is declared as a reference to a const instance of s, because f1() does not need to modify it. If it does, simply pass it as a non-const reference:
int B::f1(s &my_struct){
Now, f1() will be able to modify my_struct, and end up modifying this private instance of A's class, that was passed to it.
P.S. This has nothing to do with different translation units. Whether this whole thing is in one translation unit, or is split across half a dozen of them, classes and references work the same way.

C++ Static members of a class are initialized after constructor

I have a problem with static members of a class not being initialized before the constructor. Am i doing something wrong? Is it a bug in G++ ?
Any workarounds?
g++ --version : (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4
I am also using Eclipse as my IDE, but i just copy the static lib headers to /usr/include/StaticTestLib/InitTest.h and the library to /usr/lib/x86_64-linux-gnu/libStaticTestLib.a
Note this only happens if the object that holds the data is defined before main and the class is in a Static Library.
Static library header (the static library itself is named StaticTestLib):
InitTest.h
#include <iostream>
namespace StaticTestLib {
class notifier_header{
public:
notifier_header(){
std::cout<<"static var init"<<std::endl;
}
};
class InitTest {
public:
static notifier_header _header_notifier;
InitTest();
virtual ~InitTest();
};
}
Static library source file:
InitTest.cpp
#include "InitTest.h"
namespace StaticTestLib {
notifier_header InitTest::_header_notifier;
class notifier_cpp{
public:
notifier_cpp(){
std::cout<<"code before constructor"<<std::endl;
}
}_notifier_in_cpp;
InitTest::InitTest() {
std::cout<<"constructor"<<std::endl;
}
InitTest::~InitTest() {
std::cout<<"destructor"<<std::endl;
}
}
This program:
StaticTest.cpp
#include <iostream>
#include <StaticTestLib/InitTest.h>
StaticTestLib::InitTest test;
int main() {
std::cout << "program main" << std::endl;
std::cout << "program end" << std::endl;
return 0;
}
… outputs:
constructor
static var init
code before constructor
program main
program end
destructor
But this program:
#include <iostream>
#include <StaticTestLib/InitTest.h>
int main() {
std::cout << "program main" << std::endl;
StaticTestLib::InitTest test;
std::cout << "program end" << std::endl;
return 0;
}
… outputs:
static var init
code before constructor
program main
contructor
program end
destructor
My guess is that this is related to the order of static objects initialisation in different compilation units being undefined.
The second code snippet where you create a test object in your main is easy to explain. Static initialisation will always happen before any code is executed, so by the time you enter main, your notifier_header object is definitely created.
Now, when you create your test before main, you have two static objects. notifier_header object does not depend on your InitTest: it is scoped within that class, but it is stored in static memory. You seem to reference the notifier_header in your InitTest.cpp, which is a different compilation unit to main. A compiler is free to do static allocations in any order for those two units, provided that there is no interdependencies.
If your constructor depended on notifier_header, you could use it as a singleton. Create a function that returns an instance of a static object (headerInstance in the example below), and upon its call, the object will be created:
#include <iostream>
namespace StaticTestLib {
class notifier_header{
public:
notifier_header(){
std::cout<<"static var init"<<std::endl;
}
};
class InitTest {
public:
InitTest();
virtual ~InitTest();
notifier_header& headerInstance();
};
}
Static library source file (InitTest.cpp)
#include "InitTest.h"
namespace StaticTestLib {
class notifier_cpp{
public:
notifier_cpp(){
std::cout<<"code before constructor"<<std::endl;
}
}_notifier_in_cpp;
InitTest::InitTest() {
headerInstance();
std::cout<<"constructor"<<std::endl;
}
InitTest::~InitTest() {
std::cout<<"destructor"<<std::endl;
}
notifier_header& InitTest::headerInstance() {
static notifier_header _header_notifier; // will only be constructed once
return _header_notifier;
}
}
The output I get:
static var init
constructor
code before constructor
program main
program end
destructor

Static Functions and class variables?

I have broken down my issue into a small simple program.
I have a class myclass I have created in a separate .cpp file "classes.cpp" and declared in the header file "classes.h". myclass contains a variable a of which is initialized when instantiated. This makes variable a = 5.
My overall goal is to create a class in a separate .cpp file declared in a .h file which I can create multiple instances of in my main() program. The problem I am having is this.
In my main() function I create an instance of myclass called first.
my main program shows the variable a is set to the number 5.
If I want to change that number using a static function (and it has to be a static function as this relates to something much bigger in another program I am writing). I call the static function directly and in that static_function I create an instance of myclass and call the non_static_function because static functions have no implicit 'this' connecting them to an object.
In my non_static_function I change the value to the number 8. The problem is that the value of variable 'a' in 'first' remains at 5 when I want it to be 8. I need to change the value using first->static_function(8) and not by first->a = 8. . How can I do this?
Code below:
**main.cpp**
#include <iostream>
#include "classes.h"
using namespace std;
int main()
{
myclass *first = new myclass();
cout << "Myclass variable a is = " << first->a << endl;
first->static_function(8); // trying to change myclass variable 'a' to 8.
cout << "But" << endl;
cout << "the actual value of a is still: " << first->a << endl;
}
**classes.h**
#ifndef CLASSES_H_INCLUDED
#define CLASSES_H_INCLUDED
class myclass
{
public:
int a;
myclass();
void non_static_function(int x);
static void static_function(int x);
};
#endif // CLASSES_H_INCLUDED
**classes.cpp**
#include <iostream>
#include <cstdlib>
#include "classes.h"
using namespace std;
myclass::myclass()
{
a = 5;
}
void myclass::non_static_function(int x)
{
a = x;
cout << "The value for variable 'a' was 5 but is now: " << a << endl;
}
void myclass::static_function(int x)
{
myclass *p = new myclass();
p->non_static_function(x);
}
If you want every instance of myclass to have its own a and you want to call a static function to change it then you need to pass the instance you want changed to the static function. A static function can only modify static members of a class or the members of an instance that is inside its scope. Non static member functions can change any variable that is a member of the class.
class Foo
{
private:
int bar;
public:
static void static_function(int value, Foo & foo) { foo.bar = value; }
void non_static_function(int value) { bar = value; }
};
int main()
{
Foo foo;
Foo::static_function(8, foo);
// now bar will have the value of 8
foo.non_static_function(20);
// now bar will have the value of 20
}
I have finally found a way to deal with this small problem. Above the 'myclass' definition in classes.cpp I declare a 'myclass' variable
myclass *tgt; . Then in my constructor for 'myclass' I just allocate the instantiated object to a my global myclass variable of which I can access from the myclass definition tgt = this; Now I can use tgt in my static function to call the non_static_function in my 'myclass' definition and it all works perfectly.
NathanOliver, you are correct in saying that I need a class instance but the way I have done it here suits my needs. Passing the instance of myclass is certainly another way of doing this but it would require a global function above my 'myclass' definition.
Thanks for the help.
**main.cpp**
#include <iostream>
#include "classes.h"
using namespace std;
int main()
{
myclass *first = new myclass();
cout << "Myclass variable a is = " << first->a << endl;
first->non_static_function(8); // trying to change myclass variable 'a' to 8.
cout << "But" << endl;
cout << "The actual value of a is still: " << first->a << endl;
myclass *second = new myclass();
cout << "For the 'second' class the variable a is: " << second->a << endl;
second->non_static_function(23);
cout << "After calling the static function from 'second' the value of a is: " << second->a << endl;
cout << "And first->a is still: " << first->a << endl;
}
**classes.h**
#ifndef CLASSES_H_INCLUDED
#define CLASSES_H_INCLUDED
class myclass
{
public:
int a;
myclass();
void non_static_function(int x);
static void static_function(int x);
};
#endif // CLASSES_H_INCLUDED
**classes.cpp**
#include <iostream>
#include <cstdlib>
#include "classes.h"
using namespace std;
myclass *tgt; // *Add a global myclass variable above the myclass
definition*
myclass::myclass()
{
tgt = this; // *In the constructor allocate the instantiated class
//from main() to "tgt" .*
a = 5;
}
void myclass::non_static_function(int x)
{
a = x;
// Now see that the value of a is changed.
cout << "The value for variable 'a' was 5 but is now: "<< this->a << endl;
}
void myclass::static_function(int x)
{
tgt->non_static_function(x);
}

A line-based thread-safe std::cerr for C++

What is the easiest way to create my own std::cerr so that it is line-by-line thread-safe.
I am preferably looking for the code to do it.
What I need is so that a line of output (terminated with std::endl) generated by one thread stays as a line of output when I actually see it on my console (and is not mixed with some other thread's output).
Solution: std::cerr is much slower than cstdio. I prefer using fprintf(stderr, "The message") inside of a CriticalSectionLocker class whose constructor acquires a thread-safe lock and the destructor releases it.
If available, osyncstream (C++20) solves this problem:
#include <syncstream> // C++20
std::osyncstream tout(std::cout);
std::osyncstream terr(std::cerr);
If the above feature is not available, here is a drop-in header file containing two macros for thread-safe writing to std::cout and std::cerr (which must share a mutex in order to avoid interleaving of output). These are based on two other answers, but I have made some changes to make it easy to drop into an existing code base. This works with C++11 and forward.
I've tested this with 4 threads on a 4-core processor, with each thread writing 25,000 lines per second to tout and occasional output to terr, and it solves the output interleaving problem. Unlike a struct-based solution, there was no measurable performance hit for my application when dropping in this header file. The only drawback I can think of is that since this relies on macros, they can't be placed into a namespace.
threadstream.h
#ifndef THREADSTREAM
#define THREADSTREAM
#include <iostream>
#include <sstream>
#include <mutex>
#define terr ThreadStream(std::cerr)
#define tout ThreadStream(std::cout)
/**
* Thread-safe std::ostream class.
*
* Usage:
* tout << "Hello world!" << std::endl;
* terr << "Hello world!" << std::endl;
*/
class ThreadStream : public std::ostringstream
{
public:
ThreadStream(std::ostream& os) : os_(os)
{
// copyfmt causes odd problems with lost output
// probably some specific flag
// copyfmt(os);
// copy whatever properties are relevant
imbue(os.getloc());
precision(os.precision());
width(os.width());
setf(std::ios::fixed, std::ios::floatfield);
}
~ThreadStream()
{
std::lock_guard<std::mutex> guard(_mutex_threadstream);
os_ << this->str();
}
private:
static std::mutex _mutex_threadstream;
std::ostream& os_;
};
std::mutex ThreadStream::_mutex_threadstream{};
#endif
test.cc
#include <thread>
#include <vector>
#include <iomanip>
#include "threadstream.h"
void test(const unsigned int threadNumber)
{
tout << "Thread " << threadNumber << ": launched" << std::endl;
}
int main()
{
std::locale mylocale(""); // get global locale
std::cerr.imbue(mylocale); // imbue global locale
std::ios_base::sync_with_stdio(false); // disable synch with stdio (enables input buffering)
std::cout << std::fixed << std::setw(4) << std::setprecision(5);
std::cerr << std::fixed << std::setw(2) << std::setprecision(2);
std::vector<std::thread> threads;
for (unsigned int threadNumber = 0; threadNumber < 16; threadNumber++)
{
std::thread t(test, threadNumber);
threads.push_back(std::move(t));
}
for (std::thread& t : threads)
{
if (t.joinable())
{
t.join();
}
}
terr << std::endl << "Main: " << "Test completed." << std::endl;
return 0;
}
compiling
g++ -g -O2 -Wall -c -o test.o test.cc
g++ -o test test.o -pthread
output
./test
Thread 0: launched
Thread 4: launched
Thread 3: launched
Thread 1: launched
Thread 2: launched
Thread 6: launched
Thread 5: launched
Thread 7: launched
Thread 8: launched
Thread 9: launched
Thread 10: launched
Thread 11: launched
Thread 12: launched
Thread 13: launched
Thread 14: launched
Thread 15: launched
Main: Test completed.
Here's a thread safe line based logging solution I cooked up at some point. It uses boost mutex for thread safety. It is slightly more complicated than necessary because you can plug in output policies (should it go to a file, stderr, or somewhere else?):
logger.h:
#ifndef LOGGER_20080723_H_
#define LOGGER_20080723_H_
#include <boost/thread/mutex.hpp>
#include <iostream>
#include <cassert>
#include <sstream>
#include <ctime>
#include <ostream>
namespace logger {
namespace detail {
template<class Ch, class Tr, class A>
class no_output {
private:
struct null_buffer {
template<class T>
null_buffer &operator<<(const T &) {
return *this;
}
};
public:
typedef null_buffer stream_buffer;
public:
void operator()(const stream_buffer &) {
}
};
template<class Ch, class Tr, class A>
class output_to_clog {
public:
typedef std::basic_ostringstream<Ch, Tr, A> stream_buffer;
public:
void operator()(const stream_buffer &s) {
static boost::mutex mutex;
boost::mutex::scoped_lock lock(mutex);
std::clog << now() << ": " << s.str() << std::endl;
}
private:
static std::string now() {
char buf[64];
const time_t tm = time(0);
strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", localtime(&tm));
return buf;
}
};
template<template <class Ch, class Tr, class A> class OutputPolicy, class Ch = char, class Tr = std::char_traits<Ch>, class A = std::allocator<Ch> >
class logger {
typedef OutputPolicy<Ch, Tr, A> output_policy;
public:
~logger() {
output_policy()(m_SS);
}
public:
template<class T>
logger &operator<<(const T &x) {
m_SS << x;
return *this;
}
private:
typename output_policy::stream_buffer m_SS;
};
}
class log : public detail::logger<detail::output_to_clog> {
};
}
#endif
Usage looks like this:
logger::log() << "this is a test" << 1234 << "testing";
note the lack of a '\n' and std::endl since it's implicit. The contents are buffered and then atomically output using the template specified policy. This implementation also prepends the line with a timestamp since it is for logging purposes. The no_output policy is stricly optional, it's what I use when I want to disable logging.
This:
#define myerr(e) {CiriticalSectionLocker crit; std::cerr << e << std::endl;}
works on most compilers for the common case of myerr("ERR: " << message << number).
Why not just create a locking class and use it where ever you want to do thread-safe IO?
class LockIO
{
static pthread_mutex_t *mutex;
public:
LockIO() { pthread_mutex_lock( mutex ); }
~LockIO() { pthread_mutex_unlock( mutex ); }
};
static pthread_mutex_t* getMutex()
{
pthread_mutex_t *mutex = new pthread_mutex_t;
pthread_mutex_init( mutex, NULL );
return mutex;
}
pthread_mutex_t* LockIO::mutex = getMutex();
Then you put any IO you want in a block:
std::cout <<"X is " <<x <<std::endl;
becomes:
{
LockIO lock;
std::cout <<"X is " <<x <<std::endl;
}
An improvement (that doesn't really fit in a comment) on the approach in unixman's comment.
#define LOCKED_ERR \
if(ErrCriticalSectionLocker crit = ErrCriticalSectionLocker()); \
else std::cerr
Which can be used like
LOCKED_ERR << "ERR: " << message << endl;
if ErrCriticalSectionLocker is implemented carefully.
But, I would personally prefer Ken's suggestion.