Bug 18100 – crt_constructor not allow to init immutable

Status
RESOLVED
Resolution
WONTFIX
Severity
blocker
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2017-12-18T04:15:37Z
Last change time
2017-12-23T12:13:14Z
Assigned to
No Owner
Creator
changlon

Comments

Comment #0 by changlon — 2017-12-18T04:15:37Z
=========== code ============ static immutable int my_i ; int test(){ return 3; } shared static this(){ my_i = test(); // work } pragma(crt_constructor) extern(C) void init1(){ my_i = test(); // Error: cannot modify immutable expression my_i } ==========================
Comment #1 by changlon — 2017-12-18T04:31:36Z
crt_constructor can be call from anywhere. If so it is not able to init immutable. But if it it not able to init immutable, it will be much less useful from BetterC (compare to static this).
Comment #2 by schveiguy — 2017-12-19T15:00:12Z
I want to say this is WONTFIX. remember that init1 is simply a function, it's not a static ctor. So if you allowed it to rewrite immutable data, then something can call it later and mess up the value. If you want to do this, I think you need a cast. Not a tall order considering there are no real guarantees from D on how this will work.
Comment #3 by changlon — 2017-12-20T04:14:28Z
Hi, Steven Schveighoffer To allow set immutable will open the door for pure function and tail recursion optimization , and it is not safe to cast immutable to mutable and set value. This is why static share this is better then pragma(crt_con-/destructor). Since better D is target for high performance low level code, we should allow set immutable on crt_constructor, or drop crt_constructor and support static share this.
Comment #4 by schveiguy — 2017-12-20T14:13:57Z
(In reply to changlon from comment #3) > Since better D is target for high performance low level code, we should > allow set immutable on crt_constructor, or drop crt_constructor and support > static share this. It is allowed, you just cast :) We do it in druntime and it works fine. As long as your immutable isn't initialized, the compiler treats it as a variable when using it elsewhere. See here: https://github.com/dlang/druntime/blob/master/src/core/time.d#L2429 It's on you to make sure it isn't called elsewhere. What I don't want is to create a hole in const/immutable in the language. I'd rather you create the hole, and then guard it yourself. There are other reasons not to use shared static this to mean something different than "properly ordered static constructors" if they are tagged with extern(C) or some pragma.
Comment #5 by changlon — 2017-12-23T07:09:35Z
Thanks for explain. I just use cast and it work.
Comment #6 by ibuclaw — 2017-12-23T09:55:35Z
Right, I think this should be wontfix also. Pragma just exposes low level functionality that does not have any semantic guarantees in relation to the rest of the language. As per comment, you can use cast to write to immutable data, but you must provide your own static (probably gshared) guard to prevent multiple evaluation. This has got nothing to do with "betterC", whatever that means.
Comment #7 by schveiguy — 2017-12-23T12:13:14Z
(In reply to Iain Buclaw from comment #6) > This has got nothing to do with "betterC", whatever that means. Actually, this is all about betterC. betterC means no druntime, which means no static ctor/dtor. pragma(crt_constructor) was added as a way to hook the C library's static constructor system when you don't have druntime. But your larger point was correct.