Bugs/non-portable assumptions in libstdc++

Nathan Myers ncm-nospam@cantrip.org
Fri Nov 19 19:38:00 GMT 2004

On Fri, Nov 19, 2004 at 07:15:06PM +0100, Paolo Carlini wrote:
> >With this as background, I have two questions for the list: 1. Do you
> >agree that this is really a bug/non-portable assumption?
> >
> Well, 3.6.2/1:
>    "Objects with static storage duration (3.7.1) shall be zero 
>    initialized (8.5) before any other inizialization takes place."

This is inherited from C.  POSIX systems provide a further guarantee:
memory obtained from the OS via sbrk or anonymous mmap are also filled
with zeroes.  In other words, the static storage in question was zeroed 
by the OS before the program loader got it, so to provide 3.6.2/1 it
suffices for program initialization code not to touch that memory.

It is very common for Unix programs to rely on this.  For example, 
a zero-initialized mutex is considered unlocked, so static-duration 
mutexes are ready to use before any initialization code has had a 
chance to run.  Therefore, they are safe to use in code that may be 
called by such initialization code.  Some compilers are too stupid
to distinguish uninitialized static storage from storage explicitly
initialized to zero, so defining "static int static_int = 0;" results
in more code than does "static int static_int;".  This matters
because if other initialization code happens to write something into 
static_int, it might get zeroed out by later initialization code.

On non-POSIX systems, the language requirement might not be performed 
by the OS or program loader.  In that case the runtime has to go around
zeroing things out before it runs initializers.  Also, since some
thread packages' mutexes don't work right without being initialized, 
you have to do something nonportable to get the mutexes initialized 
extra-early, or avoid operating on mutex-protected objects during 
initialization.  Sometimes that's hard to arrange.

Nathan Myers

More information about the Libstdc++ mailing list