C++ Logo

std-proposals

Advanced search

Re: Make side effects in static initialization more consistent

From: kh <konstantin.harmuth_at_[hidden]>
Date: Tue, 22 Dec 2020 07:06:13 +0100
I don't see implementation problems with delay loaded dynamic
libraries. The wording of the behavior you gave could be changed in a
way to perform the initialization of mandatory static variables when
loading the dynamic library. I would expect a delayed
initialization/registration when delay loading a shared library. The
wording just has to be adapted. But I am not an expert about deferred
dynamic linking under windows so this might not be correct.

I would also not center the feature around initialization, I would
center it around the unwanted optimization. As long as this doesn't
happen, we get an implementation defined initialization at some point.

Regards,
Konstantin Harmuth

Am Mo., 21. Dez. 2020 um 14:09 Uhr schrieb Lénárd Szolnoki via
Std-Proposals <std-proposals_at_[hidden]>:
>
> According to cppreference.com under deffered dynamic initialization:
>
> > If no variable or function is odr-used from a given translation unit,
> > the non-local variables defined in that translation unit may never be
> > initialized (this models the behavior of an on-demand dynamic
> > library).
>
> https://en.cppreference.com/w/cpp/language/initialization#Deferred_dynamic_initialization
>
> After a quick search I didn't find normative wording that allows
> eliding initialization of variables that have deferred dynamic
> initialization. But:
>
> * For better or worse this seems to be implementation practice since a
> long time, notable examples are deferred loading of a dynamic library
> on Windows and lazy static linking on Linux.
>
> * Even if initialization were guaranteed to happen it could be too late
> for registration purposes.
>
> I see merit in the proposal, but maybe there
> are implementation challenges. It's probably solvable for static
> linking, but on-demand dynamic loading could be inherent how dynamic
> libraries work on Windows (I'm not familiar).
>
> Regards,
> Lénárd Szolnoki
>
> On Mon, 21 Dec 2020 13:12:08 +0100
> Marcin Jaczewski via Std-Proposals <std-proposals_at_[hidden]>
> wrote:
>
> > Isn't this break of As-If rule? Linker can remove variables only if
> > you cannot detect that.
> > If constructor/initialization did some not trivial thing then you can
> > clearly see the difference if it was run or not.
> > Variable itself could disappear but side effects should stay.
> >
> > It is possible that there is some clause in the standard that allows
> > this but if we fix it we should alter it not adding new things.
> >
> > pon., 21 gru 2020 o 12:06 kh via Std-Proposals
> > <std-proposals_at_[hidden]> napisał(a):
> > >
> > > Initialization of variables might carry side effects. The behavior
> > > for these effects is usually well-defined. One exception is the
> > > initialization of global variables with static storage duration.
> > >
> > > The main problem is that the linker could remove unused variables.
> > > The linker then also eliminates any side effects of the
> > > initialization. This might cause problems in some cases when the
> > > side effect is expected. The problem is strongly related to static
> > > linking. I couldn't observe it when linking the object files
> > > directly into an executable or in a shared library. This
> > > inconsistency is also problematic.
> > >
> > > Example 1: The side effect is used to register an algorithm by name
> > > that can be created without knowing the concrete type later ("self
> > > registering factory").
> > > https://godbolt.org/z/YTqEW7
> > >
> > > Example 2: Many C-Libraries need an explicit call to an init
> > > function before the library is usable. A common solution is to do
> > > this statically at one place, so it can't be forgotten.
> > >
> > > Alternatives to get the above example working with static linking:
> > > - Explicitly do the registration and do not rely on static
> > > initialization side effects.
> > > - Write this code by hand.
> > > - Perform a mock step to generate the registration code.
> > > - Use platform dependent linker flags to completely disable removal
> > > of unused symbols.
> > > - Trick the optimizer to include the unused symbols (Hacks):
> > > - Add unnecessary includes.
> > > - Place the initialization statement inside a header file.
> > > - Dummy access to static variables so the linker is not allowed
> > > to remove them.
> > > - Bugusing
> > >
> > > Possible solutions to guarantee code execution before entering
> > > main():
> > > - Add an attribute for (static) variables that should not be
> > > discarded by the linker. e.g. [[nodiscard]] or [[keep]]
> > > - No impact on existing code as it adds a new attribute that is
> > > optional. It also does not alter the default behavior.
> > > [[keep]] const auto MyUnusedVariable = InitializeSomeLibrary(); //
> > > This happens in global scope.
> > >
> > > - prevent the linker from removing static variables which have an
> > > initializer with a side effect.
> > > - Might be impossible to detect.
> > > - Could have a performance impact on existing codebases.
> > >
> > > - add a general construct to execute code before entering main(), so
> > > the user is no longer required to fake initialize with dummy
> > > variables and side effects.
> > > - Syntactic sugar for the lambda initializer combined with an
> > > execution guarantee.
> > > - The problem still exists. There is just another syntax to
> > > circumnavigate it.
> > > initialize
> > > {
> > > const auto MyUnusedVariable = InitializeSomeLibrary();
> > > }
> > >
> > > It might also be a good idea to warn when the linker throws away
> > > symbols with side effects (Which might be impossible to detect in
> > > some cases).
> > >
> > > Regards,
> > > Konstantin Harmuth
> > > --
> > > Std-Proposals mailing list
> > > Std-Proposals_at_[hidden]
> > > https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals

Received on 2020-12-22 00:06:27