Thread overview
Programming in D, page 155. shared static this() fails
1 day ago
Brother Bill
1 day ago
monkyyy
1 day ago
Brother Bill
1 day ago
monkyyy
17 hours ago
Jonathan M Davis
16 hours ago
H. S. Teoh
16 hours ago
monkyyy
1 day ago
H. S. Teoh
1 day ago
monkyyy
1 day ago
Luna
1 day ago
import std.stdio;

immutable int[] i;

shared static this() {
	writeln("In shared static this()");
	i ~= 43;
}

void main()
{
	writeln("In main()");
	writeln("i: ", i);
}

Error messages:
C:\D\dmd2\windows\bin64....\src\druntime\import\core\internal\array\appending.d(42): Error: cannot modify immutable expression px
px = (cast(T*)pxx.ptr)[0 .. pxx.length];
^
c:\dev\D\31 - 40\c33_3b_initialization_shared_static_this\source\app.d(7): Error: template instance core.internal.array.appending._d_arrayappendcTX!(immutable(int[]), immutable(int)) error instantiating
i ~= 43;
^
Failed: ["C:\D\dmd2\windows\bin64\dmd.exe", "-v", "-o-", "c:\dev\D\31 - 40\c33_3b_initialization_shared_static_this\source\app.d", "-Ic:\dev\D\31 - 40\c33_3b_initialization_shared_static_this\source"]

What changes are needed to get this to compile?
Is this syntax now obsolete? Is so, what has replaced it?

1 day ago

On Tuesday, 29 July 2025 at 22:57:50 UTC, Brother Bill wrote:

>
import std.stdio;

immutable int[] i;

shared static this() {
	writeln("In shared static this()");
	i ~= 43;
}

void main()
{
	writeln("In main()");
	writeln("i: ", i);
}

Error messages:
C:\D\dmd2\windows\bin64....\src\druntime\import\core\internal\array\appending.d(42): Error: cannot modify immutable expression px
px = (cast(T*)pxx.ptr)[0 .. pxx.length];
^
c:\dev\D\31 - 40\c33_3b_initialization_shared_static_this\source\app.d(7): Error: template instance core.internal.array.appending._d_arrayappendcTX!(immutable(int[]), immutable(int)) error instantiating
i ~= 43;
^
Failed: ["C:\D\dmd2\windows\bin64\dmd.exe", "-v", "-o-", "c:\dev\D\31 - 40\c33_3b_initialization_shared_static_this\source\app.d", "-Ic:\dev\D\31 - 40\c33_3b_initialization_shared_static_this\source"]

What changes are needed to get this to compile?
Is this syntax now obsolete? Is so, what has replaced it?

2.099.1 to 2.100.2: Success with output:
-----
In shared static this()
In main()
i: [43]
-----

version 100 was allot of safetyism changed

this compiles and was probaly the intent:

import std.stdio;

immutable(int)[] i;

shared static this() {
	writeln("In shared static this()");
	i ~= 43;
}

void main()
{
	writeln("In main()");
	writeln("i: ", i);
}
1 day ago

On Tuesday, 29 July 2025 at 23:03:41 UTC, monkyyy wrote:

>

On Tuesday, 29 July 2025 at 22:57:50 UTC, Brother Bill wrote:

>
import std.stdio;

immutable int[] i;

shared static this() {
	writeln("In shared static this()");
	i ~= 43;
}

void main()
{
	writeln("In main()");
	writeln("i: ", i);
}

Error messages:
C:\D\dmd2\windows\bin64....\src\druntime\import\core\internal\array\appending.d(42): Error: cannot modify immutable expression px
px = (cast(T*)pxx.ptr)[0 .. pxx.length];
^
c:\dev\D\31 - 40\c33_3b_initialization_shared_static_this\source\app.d(7): Error: template instance core.internal.array.appending._d_arrayappendcTX!(immutable(int[]), immutable(int)) error instantiating
i ~= 43;
^
Failed: ["C:\D\dmd2\windows\bin64\dmd.exe", "-v", "-o-", "c:\dev\D\31 - 40\c33_3b_initialization_shared_static_this\source\app.d", "-Ic:\dev\D\31 - 40\c33_3b_initialization_shared_static_this\source"]

What changes are needed to get this to compile?
Is this syntax now obsolete? Is so, what has replaced it?

2.099.1 to 2.100.2: Success with output:
-----
In shared static this()
In main()
i: [43]
-----

version 100 was allot of safetyism changed

this compiles and was probaly the intent:

import std.stdio;

immutable(int)[] i;

shared static this() {
	writeln("In shared static this()");
	i ~= 43;
}

void main()
{
	writeln("In main()");
	writeln("i: ", i);
}

Your changes do work, but at the cost of making i NOT deeply immutable: no assignment, no changing any elements, no appending, no setting length. This syntax permits appending and setting length, with no assignment and no changing any elements.

The idea of shared static this() is that is has "special" privileges to mutate immutable slices and other references. These run prior to main, so it is "safe" to make mutations at this early point.

I would like to execute the original code.

1 day ago

On Tuesday, 29 July 2025 at 23:18:18 UTC, Brother Bill wrote:

>

Your changes do work, but at the cost of making i NOT deeply immutable: no assignment, no changing any elements, no appending, no setting length.

if you insit on the type id suggest this code then

import std.stdio;

immutable int[] i;

shared static this() {
    writeln("In shared static this()");
    int[] i_;
    i_~=43;
    foreach(j;0..10){
        i_~=j;
    }
    i = i_.dup;
}

void main()
{
	writeln("In main()");
	writeln("i: ", i);
}

this error message is ugly for a newer one; is this a regression? Programming in d is sorta spec tier

2.101.2: Failure with output:
-----
/path/to/dmd.linux/dmd2/linux/bin64/../../src/druntime/import/core/internal/array/appending.d(49): Error: cannot modify `immutable` expression `px`
onlineapp.d(6): Error: template instance `core.internal.array.appending._d_arrayappendcTXImpl!(immutable(string), immutable(char))` error instantiating
-----

2.102.2 to 2.105.3: Failure with output:
-----
/path/to/dmd.linux/dmd2/linux/bin64/../../src/druntime/import/core/internal/array/appending.d(47): Error: cannot modify `immutable` expression `px`
onlineapp.d(6): Error: template instance `core.internal.array.appending._d_arrayappendcTXImpl!(immutable(string), immutable(char))` error instantiating
-----

Since      2.106.1: Failure with output:
-----
/path/to/dmd.linux/dmd2/linux/bin64/../../src/druntime/import/core/internal/array/appending.d(42): Error: cannot modify `immutable` expression `px`
onlineapp.d(6): Error: template instance `core.internal.array.appending._d_arrayappendcTX!(immutable(string), immutable(char))` error instantiating
1 day ago
On Tue, Jul 29, 2025 at 10:57:50PM +0000, Brother Bill via Digitalmars-d-learn wrote:
> ```
> import std.stdio;
> 
> immutable int[] i;
> 
> shared static this() {
> 	writeln("In shared static this()");
> 	i ~= 43;
> }

`i` is immutable, so it's illegal to use mutating operations like ~= on it.

But since you're inside a static module ctor, you can assign to the array instead:

	i = [ 43 ];

should work.


T

-- 
Why does this impressionist painting look like coins falling from the sky?  It's Cloud Monet.
1 day ago

On Tuesday, 29 July 2025 at 22:57:50 UTC, Brother Bill wrote:

>
import std.stdio;

immutable int[] i;

shared static this() {
	writeln("In shared static this()");
	i ~= 43;
}

void main()
{
	writeln("In main()");
	writeln("i: ", i);
}

Error messages:
C:\D\dmd2\windows\bin64....\src\druntime\import\core\internal\array\appending.d(42): Error: cannot modify immutable expression px
px = (cast(T*)pxx.ptr)[0 .. pxx.length];
^
c:\dev\D\31 - 40\c33_3b_initialization_shared_static_this\source\app.d(7): Error: template instance core.internal.array.appending._d_arrayappendcTX!(immutable(int[]), immutable(int)) error instantiating
i ~= 43;
^
Failed: ["C:\D\dmd2\windows\bin64\dmd.exe", "-v", "-o-", "c:\dev\D\31 - 40\c33_3b_initialization_shared_static_this\source\app.d", "-Ic:\dev\D\31 - 40\c33_3b_initialization_shared_static_this\source"]

What changes are needed to get this to compile?
Is this syntax now obsolete? Is so, what has replaced it?

I think the issue is that you’re appending. An immutable type can only be set once by a constructor so you’d want to set it directly to an array literal if I remember correctly.

1 day ago
On Tuesday, 29 July 2025 at 23:48:58 UTC, H. S. Teoh wrote:
> 
> `i` is immutable, so it's illegal to use mutating operations like ~= on it.

@luna

The question should be if programming in d (page 177 https://ddili.org/ders/d.en/Programming_in_D.pdf) should be authoritive here

> It is possible to mutate const and immutable variables in shared static this()
blocks:

```d
import std.stdio;

immutable char[3] s;

shared static this() {
	s[0]='b';
    s[1]='a';
    s[2]='r';
}

void main(){
	writeln("In main()");
	writeln("s: ", s);
}
```
> Since      2.099.1: Success with output:

Im on op side now thinking whatever templated core.appender maybe partially unimplemented during the 100 changes
17 hours ago
On Tuesday, July 29, 2025 5:18:18 PM Mountain Daylight Time Brother Bill via Digitalmars-d-learn wrote:
> Your changes do work, but at the cost of making i NOT deeply immutable: no assignment, no changing any elements, no appending, no setting length.  This syntax permits appending and setting length, with no assignment and no changing any elements.
>
> The idea of shared static this() is that is has "special" privileges to mutate immutable slices and other references. These run prior to main, so it is "safe" to make mutations at this early point.
>
> I would like to execute the original code.

The original code is not supposed to work. It's a violation of the type system to mutate const or immutable data, and allowing the mutation of a const or immutable variable at any point - even in a constructor - is a hole in the type system which can cause subtle bugs. A const or immutable variable is initialized with a value (either by default initialization or by explicitly giving it a value), but it can't be mutated after that.

What's special about a shared static constructor is that it's allowed to give an immutable module-level variable its initial value instead of requiring that the variable be initialized directly with a value via CTFE (compile time function evaluation), since directly initializing a module-level variable would be done with a value that's generated at compile time. So, instead of doing something like

immutable int[] i = [foo(), bar()];

the shared static constructor makes it possible to do the initialization at runtime, e.g.

immutable int[] i;

shared static this()
{
    immutable(int)[] temp;
    temp ~= foo();
    temp ~= bar();
    i = temp;
}

But even the shared static constructor isn't allowed to mutate the value of i. It's allowed to initialize it exactly once. This is the same with constructors for user-defined types, e.g.

class C
{
    immutable int[] arr;

    this()
    {
        arr ~= 42;
    }
}

will fail to compile, because it's attempting to mutate the immutable member variable, whereas something like

class C
{
    immutable int[] arr;

    this()
    {
        immutable(int)[] temp;
        temp ~= 42;
        temp ~= 57;
        arr = temp;
    }
}

would be legal.

There have been bugs with initializing const and immutable variables in constructors in the past which made it possible to mutate const or immutable variables, and the language has been tightened to fix such holes. Any more holes that exist will hopefully be found and fixed, but it's very much purposeful that your example code does not compile.

This is part of why copy constructors were introduced to replace postblit constructors (though that's still a work in progress with regards to dynamic arrays and AAs, since the work to fully implement support for copy constructors for them is still being worked on). Postblit constructors were designed with the idea that the constructor would first copy the struct and then modify any member variables which needed modification afterwards (e.g. by doing a deep copy) instead of requiring that each member be explicitly initialized, but making that work required temporarily treating const and immutable data as if it were mutable, and that could result in it being mutated, which violates the guarantees that the type system is supposed to provide with const and immutable.

So, work has been done to make it so that D no longer has anywhere where it allows a constructor to mutate const or immutable variables. Constructors can initialize such variables, but the variables aren't allowed to be mutated.

If you want to be able to have a mutable variable that you then use to
initialize an immutable variable, then that mutable variable needs to be a
separate variable that is then used to give the immutable variable its
value. For types with no indirections, this can typically be done
simply by initializing the immutable variable with the mutable variable,
because the value is simply copied, but for types with indirections, either
a deep copy must be made, or it must be cast to immutable (which is @system,
because it will violate the type system if any of that data is then mutated
via a mutable reference after that).

So, you could do something like

shared static this()
{
    int[] temp;
    temp ~= foo();
    temp ~= bar();
    i = temp.idup;
}

or

shared static this()
{
    int[] temp;
    temp ~= foo();
    temp ~= bar();
    i = cast(immutable) temp; // @system
}

if you wanted operate on a fully mutable array, but the type system is supposed to guarantee that immutable data is never mutated, so the compiler does not allow you to mutate an immutable variable even in a constructor. It just allows you to initialize it.

- Jonathan M Davis




16 hours ago
On Wed, Jul 30, 2025 at 10:54:15AM -0600, Jonathan M Davis via Digitalmars-d-learn wrote: [...]
> immutable int[] i;
> 
> shared static this()
> {
>     immutable(int)[] temp;
>     temp ~= foo();
>     temp ~= bar();
>     i = temp;
> }
> 
> But even the shared static constructor isn't allowed to mutate the value of i. It's allowed to initialize it exactly once.
[...]

In that case, there is a bug:

```
static immutable int[] data;
shared static this() {
	data = [ 1 ];
	data = [ 2 ];	// should not compile, but currently does
}
```


T

-- 
Why did the chicken cross the Möbius strip?  To get to the same side!
16 hours ago
On Wednesday, 30 July 2025 at 18:00:39 UTC, H. S. Teoh wrote:
> On Wed, Jul 30, 2025 at 10:54:15AM -0600, Jonathan M Davis via Digitalmars-d-learn wrote: [...]
>> immutable int[] i;
>> 
>> shared static this()
>> {
>>     immutable(int)[] temp;
>>     temp ~= foo();
>>     temp ~= bar();
>>     i = temp;
>> }
>> 
>> But even the shared static constructor isn't allowed to mutate the value of i. It's allowed to initialize it exactly once.
> [...]
>
> In that case, there is a bug:
>
> ```
> static immutable int[] data;
> shared static this() {
> 	data = [ 1 ];
> 	data = [ 2 ];	// should not compile, but currently does
> }
> ```
>
>
> T

please dont "fix" that; navigating the ct-gc type system is a bit tricky as is Id hate to see one of the useful bugs be destoried on accident