Static initialization order fiasco in gflags

282 views
Skip to first unread message

Adrian Colley

unread,
Jun 17, 2014, 11:45:45 AM6/17/14
to google...@googlegroups.com
I'm curious how gflags avoids the problem of varying order of initialization of static-lifetime variables. The comments in the code indicate clearly that a lot of thought has gone into it, but the code itself contains a couple of things which look like bugs. Well, they look like bugs to me.

The static initialization order fiasco problem is well-known: after program startup but before main() is called, all the static-lifetime variables with non-constexpr initializer expressions are initialized in no particular order. If one of those expressions implicitly assumes that another global variable has already completed its initialization, then disaster results.

Gflags relies on construction and use of map and string objects at static-initialization time. Those are non-POD classes. Nothing in the language standard promises that they won't rely on dynamically-initialized static variables.

So, how do we know that a DEFINE_string won't be run before the initializer for a hidden static variable inside the map implementation? If an implementation has such a hidden static var, and the map constructor depends on it not being zero, then the world will collapse randomly on program startup.

Now, what saves the world here? Is map required by something to be fully operational before dynamic initialization begins? If so, by what? Or is there another cunning plan which prevents this being a problem? Or, is it just a problem?

 --Adrian.
professional nit-picker

Massimo Del Zotto

unread,
Jun 18, 2014, 1:45:53 PM6/18/14
to google...@googlegroups.com
That's indeed a good question. From what I recall (I think I looked at it a couple years ago) gflags seems to be happy allocating the buffers. It didn't seem concerned with the fact they could still be filled with garbage.

I think the original author had quite a project in mind. For that reason, he probably left gflags leaking in its design.

I'll keep an eye on this thread.

Massimo


--
You received this message because you are subscribed to the Google Groups "google-gflags" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-gflag...@googlegroups.com.
To post to this group, send email to google...@googlegroups.com.
Visit this group at http://groups.google.com/group/google-gflags.
For more options, visit https://groups.google.com/d/optout.

Andreas Schuh

unread,
Jun 18, 2014, 8:21:23 PM6/18/14
to google...@googlegroups.com
My personal opinion on this is that no command-line flag variable should ever be used in any code that may be evaluated during static initialization time. I don't think this would ever be necessary as this would only mean that the flag's default value is meant to be used by that code at this time during program execution. But in this case, I would use a separate constant for the default value which should be a POD and can be used in the code called during static initialization as well as the default flag value argument of the DEFINE flag macros.

This means in particular that I think that a flag variable should not be used in constructor implementations. After all, flags are command-line options/parameters of a program and their value rather meaningless before these command arguments have been parsed. As this happens at the begin of the main function after static variables were initialized, flag values should not be read (or even set) during static initialization.

Adrian Colley

unread,
Jun 19, 2014, 8:15:19 AM6/19/14
to google...@googlegroups.com
On 19 June 2014 01:21, Andreas Schuh <andreas....@gmail.com> wrote:
> My personal opinion on this is that no command-line flag variable should
> ever be used in any code that may be evaluated during static initialization
> time.

I agree, but discussion of the use of flags is off-topic. I'm
concerned that the mere definition of a flag may trigger a disaster at
static initialization time. The DEFINE macros indirectly call
map::insert, you see, and we don't know that map::insert is safe to
run at static initialization time.

--Adrian.

Andreas Schuh

unread,
Feb 19, 2016, 6:36:54 AM2/19/16
to google-gflags
Seems I've never responded to your comments...

> I agree, but discussion of the use of flags is off-topic.

I don't think it is when the conclusion would be that we should move on to using actual string types for the static variables without any placement new hack. Discussing the use and purpose of the current code is necessary to understand whether it is really necessary. IMHO, it is not and was maybe the result of a wrong belief or design decision.

> The DEFINE macros indirectly call map::insert, you see, and we don't know that map::insert is safe to run at static initialization time.

It does, but this call only deals with pointers to the static object memory. It is no problem when the string objects themselves are not initialised yet at this time as long as no functions/members of these objects are used before.

> we don't know that map::insert is safe to run at static initialisation time.

I would say it is safe for the purpose of registering the "CommandLineFlag" instance.
Reply all
Reply to author
Forward
0 new messages