On Mar 31, 2013, at 1:39 AM, WenHan Gu (谷汶翰) <[email protected]> wrote:

> 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?

The linker orders inits "from bottom up", where the direction is defined by 
what links to what.  For dylib A to use std::cout, it must link to libc++.  
This causes the linker to run libc++'s global inits prior to those in dylib A.

> 
> 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.

The idiom gcc has, and that you suggest, is what is recommended by the 
standard.  The libc++ implementation of it, combined with the linker behavior 
on OS X / iOS, is a conforming optimization of that idiom.

Howard

> 
> 
> 2013/3/30 Howard Hinnant <[email protected]>
> On Mar 5, 2013, at 2:35 AM, WenHan Gu (谷汶翰) <[email protected]> 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)


_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to