[libc++] [PATCH] global object initialization bug

WenHan Gu (谷汶翰) wenhan.gu at gmail.com
Sat Mar 30 22:39:41 PDT 2013


Yes, thanks for your review.

However, in program P uses different dynamic libraries A and B,
if A's global objects init by B's global objects, It might have the same
problem even on __APPLE__ right?

Actually, Someone told me programmer should not rely on this idiom.
He said, if the program uses global object init depending on another
component's global object init.
This program should be considered wrong.

I've no idea whether I should submit this patch,
It seems it is a tricky that only GNU libstdc++ has.


2013/3/30 Howard Hinnant <hhinnant at apple.com>

> On Mar 5, 2013, at 2:35 AM, WenHan Gu (谷汶翰) <wenhan.gu at gmail.com> wrote:
>
> > Hi all,
> >
> > If I use cerr/cout... before main function, it may potentially cause
> use-before-init before this patch.
> >
> > This is a tiny patch, but important to guarantee init-before-use.
> > Please review it. Thanks!!
> >
> >
> > ===
> >
> > Long explanation:
> >
> > std::cout, cerr, ... are global objects that should be initialized
> before use. However, C++ does not guarantee an order of initialization
> between static objects in different translation units.
> > One basic idiom is that declares a static object that gets created in
> every translation unit that includes <iostream>. This object has a static
> constructor and destructor that initializes and destroys the global
> iostream objects before they could possibly be used in the file.
> > In GNU libstdc++, it is at
> > <libstdc++>/include/std/iostream: static ios_base::Init __ioinit;
> > but in libcxx, it is at src/iostream.cpp, i.e., it only guarantee
> initialized when entering main function. If we use them before main, it may
> cause undefined behavior since it is a use-before-init bug.
> >
> > Thanks!
>
> Sorry for the long delay in reviewing this patch.
>
> If this patch is to be committed, it will have to be #ifdef'd out on
> __APPLE__.  On Apple platforms we have an additional guarantee: if A links
> against B, B's initializer will be run before A's.
>
> I.e. if you link to libc++.dylib, then cout et al. are guaranteed to be
> constructed before your initializers run.
>
> Use of this guarantee is a deliberate design decision.  It greatly reduces
> the number of global constructors (-Wglobal-constructors) in a program.
>  This in turn can increase launch time performance.
>
> Howard
>
>


-- 
Best Regards,
WenHan Gu (Nowar)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130331/176d1c8a/attachment.html>


More information about the cfe-commits mailing list