-
-
Notifications
You must be signed in to change notification settings - Fork 665
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Static initializer side effects occur at very different time on C# target #4091
Comments
I wish this was defined to be undefined behavior, but alas it isn't. It requires running every single static initialization as part of the boot process which entails loading every single type that has a static initialization. Depending on the nature of the application this is quite a bit of a concession with regards to boot time. And all that for an incomplete feature (static initialization order in the general case is undecidable). Well, I guess Java and C# are going to have to comply. |
Is this not undefined behaviour? I am quite sure that it is: #125 (btw, check the author ;) ) |
I think it's quite bad if we need to make this a defined behaviour. Making sure that all |
Both ways seem to have serious downsides, but generally speaking it seems good for a programming language intended to be compilable to different targets to actually act the same (or reasonably similarly in the face of hard limits) across its targets. Maybe the ideal way would be to have it default to init on boot, but have a compiler flag to optionally turn off that boot-time behavior? |
#125 was about init, which is unspecified. Regarding statics initialization, we usually use some kind of heuristic to sort the classes based on their dependencies, they are then passed to the code generator in the sorted order. I guess for C# that would mean to have a single staticsInit() function that assign all statics for all the types before calling main() |
to be honest i'd like to keep current behaviour instead of having to remember to call some init function when using haxe/c# generated code from native c# target code. |
I think it's unfortunate if we have to do that - there is benefit in lazily loading types as needed, and what we gain instead seems to be quite dubious. I'd propose that we only enforce this if a flag is defined. |
This is a long shot, but does the new static analyzer know which static data is affected via side-effects from other statics? If so, the system could boot-time initialize only the ones that really require it. |
No interprocedural analysis. I'd add "yet" but I doubt I'll ever travel down that path. |
I agree this should not be a requirement |
I think this has become a documentation issue. |
Static initializers are run at an unusual time on the C# target, leading to very different static initializer side effect results from other platforms. In C#, only creating an instance of Foo or referring to any of Foo's static members will trigger a just-in-time call to Foo's static initializers via the C# Foo static constructor. This is not true on other platforms such as flash, where the static initializer will be called much earlier, seemingly during the boot phase. (See http://old.haxe.org/doc/advanced/magic)
This can cause major problems for code that relies on static initializer side effects having occurred by the time non-static normal code is run. Example use cases include things like classes registering themselves by some sort of moniker. In these cases the registration will not have occurred yet in C# unless someone has already explicitly created a new Foo or referred to one of its static members, even though that will work fine on other targets. (Maybe not all?)
The text was updated successfully, but these errors were encountered: