
Data initialization in C++ - Tsiolkovsky
http://woboq.com/blog/data-and-initialisation.html
======
apaprocki
File-level static non-POD instances are a big no-no. If you really (really)
need a global static, move it into function scope in a function which returns
the static (singleton pattern). (Additional tricks can be used to ensure it is
only initialized once in a thread-safe manner.)

e.g.
[https://github.com/bloomberg/bsl/blob/master/groups/bsl/bslm...](https://github.com/bloomberg/bsl/blob/master/groups/bsl/bslma/bslma_mallocfreeallocator.cpp#L40)

~~~
nanidin
Static init/de-init order were huge issues at my last job, working on embedded
devices. When I say huge, I really mean issues that would seem to come and go
randomly with builds, and in some cases brick devices until someone could JTAG
it and get it up on a debugger to load a new boot block or determine the root
cause. As the guy that got to do this, let me tell you that stepping through
the ARM assembly of the runtime library made me feel like an uber hacker, but
it wasn't exactly fun.

The nifty counter pattern[0] ended up being the most helpful for generating a
static initialization and de-initialization order without conflicts. The
tradeoffs are that it increases codesize and that it looks like magic to a lot
of people. I don't remember the exact reason that wrapping everything in
functions returning references didn't work - I think it was more to do with
the de-init side of things, since the function wrappers guarantee the init
order but not the de-init order.

[0]
[http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Nifty_Count...](http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Nifty_Counter)

~~~
huhtenberg
Uhm... but why would you have globals with constructors in a code where
de/initialization order matters?

~~~
nanidin
Massive, legacy codebase, C wrappers around new C++ functionality... to be
honest I don't remember the exact reason. It mostly had to do with concurrency
primitives not being initialized when they needed to be due to a lack of a way
to initialize a class instance the same way POD instances are initialized (aka
int x = 0 in global scope.)

You work with what you're given, sometimes! ;)

------
kruhft
This is my first exposure to constexpr and it looks very interesting.
According to this article it's a second C++ metaprogramming language:
[http://cpptruths.blogspot.ca/2011/07/want-speed-use-
constexp...](http://cpptruths.blogspot.ca/2011/07/want-speed-use-constexpr-
meta.html).

The more I learn about C++11 the more I like it. There's some really amazing
new features that I've only seen in Lisps, plus there's full static typing,
which is the one thing I miss from Lisps.

~~~
pubby
The more I use C++11 the less I like it.

constexpr has many problems:

\- Its syntax is that of C++s, but limited to a single statement and so is
about as expressive as a block of wood. Templates are much closer to
functional languages and so are naturally more expressive. Seriously, use
templates instead!

\- It's inefficient. If you want to do heavy computations then you're better
off writing a program to generate code. If you want efficient run-time
performance then good luck optimizing a single statement.

\- It's specification is full of quirks and pitfalls. Quite simply, constexpr
does not follow the path of least surprise. Plus, I hear it was a nightmare
for the compiler writers.

~~~
kruhft
After reading up on Lisp macro programming (PG's on OnLisp and others) you
will see that it is always advised to use only purely functional code when
doing metaprogramming. In Common Lisp and all the others Lisps I've seen, this
is not strictly enforced by the language and only advised. The code should be
purely functional because you don't know when and how many times it can be
called by the compiler leading to some grand mysteries when something does not
go as expected during compilation due to unintended state.

The constexpr design is taking this to heart and enforcing that the code to be
purely functional. I don't see this as a disadvantage but take it that
designers of C++ are forcing best practices for the features they are adding.
Best practices are generally not the most convenient, but by doing it this
way, they're giving you less 'rope to shoot yourself in the foot'. Lisp was
more of a research language woring as a testbed of features that are now
moving into mainstream languages now that there is some experience with how to
use them in the least damaging way.

Purely functional programming is not as 'easy' to write because almost
everyone learns imperative first, which is the most natural way to code (do
this, then do this, then do this,...). Using functional code requires you put
the control that you would normally put into code into the _data_. It's a
different way of thinking and is not natural in the way that imperative
programming is.

And regarding that implementing constexpr wsa a 'nightmare for compiler
writers', it should be! Strong abstractions are difficult to design and
implement, but once they are complete everyone benefits. Compilers are the one
things that should take on the hard features since everyone uses them.

Thanks for your experiences with constexpr and I'll form my own opinions of it
after some practial use and maybe i'll find it just as lacking as you do in
the end :). I'll stand by my statement that C++11 is heading in the right
direction, even though it may have some warts and tradeoffs that it can't be
avoided, like anything that matures. It will be interesting to see what C++
goes in the next 10 or more years.

~~~
pubby
Hi! Thanks for your thoughts :)

I pretty much agree with everything you said, with the exception of defending
constexpr. What follows is more ranting on constexpr and praise for templates.

> The constexpr design is taking this to heart and enforcing that the code to
> be purely functional.

You're falling into the common trap of confusing purity with functional.
constexpr is only enforcing code to be free of side effects; it's even less
functional than C.

Templates on the other hand, are functional. With templates, you get pattern
matching, easy recursive data types, high order functions, and more. You can
literally take Haskell code, change the syntax a bit, and end up with a
complete metaprogram. That's not possible with constexpr.

Templates can work with values, but more importantly, they can work with
types. Being able to actually to modify the types and code of the program is
essential to metaprogramming. None of that comes with constexpr. Hell, I
wouldn't even consider constexpr to be metaprogramming.

In addition, templates can actually form abstractions, even ones that aren't
functional. Boost.MPL, over a decade old, emulated C++-style containers at
compile time using only templates. As a personal experience, I've implemented
a stack-based language akin to Forth using templates, see:
[http://pubby8.wordpress.com/2012/10/15/stack-based-
template-...](http://pubby8.wordpress.com/2012/10/15/stack-based-template-
metaprogramming-in-c-11/)

Well guess what? Templates suck. They slow the compile down to a crawl, their
syntax is incomprehensible, and don't get me started on their error message.
The only reason to use them is because there is nothing better.

C++11 had a chance to fix this. Instead, we got constexpr.

