[llvm-dev] "Do not use Static Constructors" LLVM Coding Standard rule question

Craig, Ben via llvm-dev llvm-dev at lists.llvm.org
Wed Mar 9 08:04:42 PST 2016


I would not recommend the leaky static construct (e.g. "static const foo 
&f = *new foo();").  If LLVM is built as a dynamic library, it can be 
unloaded and reloaded an indefinite number of times, and each one of 
those iterations will leak one instance of 'foo'.

Also, if LLVM is built by Windows MSVC 2013 (which LLVM supports), then 
function level static creation is not thread safe (it is thread safe 
with MSVC 2015).  This can really get you in trouble if you also use 
LTO, as some LTO variants will internally create a thread for each object.


On 3/9/2016 9:59 AM, David Blaikie via llvm-dev wrote:
>
> Oh, yes, for sure. This should not be used for any dynamic state. Such 
> a thing can only used as an immutable singleton of sorts.
>
> If it is mutable then you break the usual thread safety guarantees 
> -two separate threads using two separate llvm contexts shouldn't 
> interfere with each other.
>
> Not to mention, as you said, can break ongoing uses of llvm by 
> accumulating cruft. That's what the llvmcontext is for - all that 
> mutable state we can't find a better place for ;)
>
> The leak itself is acceptable though, if those conditions are met. So 
> if you just need the map for some fixed lookup table, the solution I 
> suggested should be OK. It won't produce an unrecoverable growing 
> memory drain, etc.
>
> On Mar 9, 2016 2:31 AM, "mats petersson" <mats at planetcatfish.com 
> <mailto:mats at planetcatfish.com>> wrote:
>
>     These type of constructs are less than ideal if you have something
>     that uses LLVM as a library in a "long running" application (e.g.
>     imagine something like photo editor that compiles "filters", and a
>     user that loads the application on monday, and closes it on the
>     following thursday) , as there is no (trivial) way to know that
>     this stringmap exists, or that it may need cleaning out between
>     two compilations, for example. The risk with such constructs is
>     that they build up over time, and appear to be "memory leaks".
>
>     --
>     Mats
>
>     On 9 March 2016 at 09:45, valery pykhtin via llvm-dev
>     <llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>> wrote:
>
>         Right, but it produces a mem leak, I'm not sure what is worse :-)
>
>         On Wed, Mar 9, 2016 at 10:49 AM, David Blaikie
>         <dblaikie at gmail.com <mailto:dblaikie at gmail.com>> wrote:
>
>             a static local still produces a static dtor, though
>
>             One of the ways you can get around this is with a
>             deliberate non-cleanup:
>
>             const foo &getFoo() {
>               static const foo &f = *new foo();
>               return f;
>             }
>
>             that way no global dtor runs. Obviously only works if you
>             don't need foo's dtor to run.
>
>             On Tue, Mar 8, 2016 at 11:42 PM, Craig Topper via llvm-dev
>             <llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>>
>             wrote:
>
>                 I believe the rule is only for global variables. At
>                 least that's what the first sentence in the section says.
>
>                 "Static constructors and destructors (e.g. global
>                 variables whose types have a constructor or
>                 destructor) should not be added to the code base, and
>                 should be removed wherever possible."
>
>                 On Tue, Mar 8, 2016 at 10:52 PM, valery pykhtin via
>                 llvm-dev <llvm-dev at lists.llvm.org
>                 <mailto:llvm-dev at lists.llvm.org>> wrote:
>
>                     Hi,
>
>                     I'm new here and have a question about the rule in
>                     title. Is the following use case also prohibited?
>
>                     int findNameId(StringRef Name)
>                     {
>                        static StringMap<int> Map = createSomeIDMap();
>                        return Map.lookup(Name);
>                     };
>
>                     It seems it isn't influence startup time and
>                     doesn't create initialization order problems.
>                     Clang isn't complaining about it with
>                     -Wglobal-constructor flag.
>
>                     I'm asking because under some interpretation of
>                     rule wording it can be called static constructor too.
>
>                     Thanks,
>                     Valery
>
>                     _______________________________________________
>                     LLVM Developers mailing list
>                     llvm-dev at lists.llvm.org
>                     <mailto:llvm-dev at lists.llvm.org>
>                     http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>
>
>
>
>                 -- 
>                 ~Craig
>
>                 _______________________________________________
>                 LLVM Developers mailing list
>                 llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>
>                 http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>
>
>
>
>         _______________________________________________
>         LLVM Developers mailing list
>         llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>
>         http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>
>
>
>
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

-- 
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160309/142607de/attachment.html>


More information about the llvm-dev mailing list