Jump to page: 1 2
Thread overview
is my code to get CTFE instantiated object valid D ?
May 27, 2016
chmike
May 27, 2016
Kagamin
May 28, 2016
chmike
May 28, 2016
Mike Parker
May 28, 2016
Mike Parker
May 28, 2016
ag0aep6g
May 29, 2016
Mike Parker
May 29, 2016
Mike Parker
May 28, 2016
Kagamin
May 28, 2016
chmike
May 28, 2016
chmike
May 28, 2016
ag0aep6g
May 27, 2016
Era Scarecrow
May 28, 2016
chmike
May 28, 2016
ag0aep6g
May 29, 2016
chmike
May 29, 2016
chmike
May 27, 2016
I need to create an app wide singleton instance for my class.
The singleton is immutable, but I want to allow mutable references to that singleton object so that I can do fast 'is' tests.

I declared this

class Category
{
     protected static immutable Category instance_ = new Category;
     Category instance() { return cast(Category)instance_; }
     ...
}

It compiles and the instance should be instantiated at compile time. I couldn't check yet.

The public interface of Category is designed so that the object's state can't be modified and thus remains immutable.

Is this code valid D or is the behavior undefined due to the cast ?


A variant implementation would have a method that modifies the object but only internally and in a very controlled way to store strings in a cache for faster access. Would it still be valid D code ?
May 27, 2016
On 5/27/16 4:20 PM, chmike wrote:
> I need to create an app wide singleton instance for my class.
> The singleton is immutable, but I want to allow mutable references to
> that singleton object so that I can do fast 'is' tests.
>
> I declared this
>
> class Category
> {
>       protected static immutable Category instance_ = new Category;
>       Category instance() { return cast(Category)instance_; }
>       ...
> }
>
> It compiles and the instance should be instantiated at compile time. I
> couldn't check yet.
>
> The public interface of Category is designed so that the object's state
> can't be modified and thus remains immutable.
>
> Is this code valid D or is the behavior undefined due to the cast ?

You can cast away immutable. You just can't mutate. Hard to say without seeing what the ... is.

> A variant implementation would have a method that modifies the object
> but only internally and in a very controlled way to store strings in a
> cache for faster access. Would it still be valid D code ?

No. Undefined behavior if you modify immutable data.

-Steve
May 27, 2016
On Friday, 27 May 2016 at 20:20:36 UTC, chmike wrote:
> Is this code valid D or is the behavior undefined due to the cast ?

A mutable object can be synchronized on:
synchronized(Category.instance){}
This will create and store a mutex in the object (sad but true, design taken from java). If the immutable object is in readonly memory, it will crash on write.
May 27, 2016
On Friday, 27 May 2016 at 20:20:36 UTC, chmike wrote:
> The public interface of Category is designed so that the object's state can't be modified and thus remains immutable.

 Then... why cast away immutable?

 I suppose there's always a core set of variables that are what the object actually considers for it's constness, while there's other extra ones for convenience (say lookup hash tables, memoize and the like) which assist but their presence or lack thereof only affects speed rather than function...
May 28, 2016
On Friday, 27 May 2016 at 21:41:02 UTC, Kagamin wrote:
> On Friday, 27 May 2016 at 20:20:36 UTC, chmike wrote:
>> Is this code valid D or is the behavior undefined due to the cast ?
>
> A mutable object can be synchronized on:
> synchronized(Category.instance){}
> This will create and store a mutex in the object (sad but true, design taken from java). If the immutable object is in readonly memory, it will crash on write.

That is a good argument. Thanks. It would indeed be a good idea to put immutable objects in a read only portion of the code.

Would it be different if the object was declared const instead of immutable ?

I want compile time instantiation and mutable references to the object. Apparently only immutable and const objects can be instantiated at compile time. I also want an app wide singleton (not stored in TLS). If I use _gshared I apparently wouldn't get a compile time instantitation.

It's to implement the flyweight pattern. I don't want to use Rebindable because the assembly code generated by dmd is currently inefficient. Rebindable cast away the const but the non constant reference is not exposed.

What is the difference between a const and immutable object ? would a const object be allowed to modify itself by using a hash table or caching results inside ? Is a static const Category c variable a TLS variable ?

This is a bit frustrating because it is trivial to implement in C and C++.


May 28, 2016
On Saturday, 28 May 2016 at 05:30:26 UTC, chmike wrote:

> What is the difference between a const and immutable object ? would a const object be allowed to modify itself by using a hash table or caching results inside ?

The difference lies in the guarantees of const and immutable.

Foo f = new Foo;
const(F) cf = f;

The above is legal. The single instance can modify itself in methods called via f, but not those called via cf. So the answer to the second question is no, not directly.

Foo f = new Foo;
immutable(f) if = f;

This will not compile. The compiler expects that any reference assigned to if will not be modified anywhere in the program, ever. It does not have the same expectation of const references.

> Is a static const Category c variable a TLS variable ?

Yes. All variables are TLS unless explicitly marked with __gshared or shared.
May 28, 2016
On Saturday, 28 May 2016 at 08:34:17 UTC, Mike Parker wrote:

> const(F) cf = f;
> immutable(f) if = f;

And, of course, those should be const(Foo) and immutable(Foo).
May 28, 2016
On Saturday, 28 May 2016 at 05:30:26 UTC, chmike wrote:
> Would it be different if the object was declared const instead of immutable ?

Sometimes compiler is able to figure out that const data is immutable.

> This is a bit frustrating because it is trivial to implement in C and C++.

For a trick of static mutable allocation see https://github.com/dlang/druntime/pull/1325
May 28, 2016
On Saturday, 28 May 2016 at 08:47:48 UTC, Kagamin wrote:
> For a trick of static mutable allocation see https://github.com/dlang/druntime/pull/1325

Thank you that looks promising. I'll study an experiment with the code.
If I would like that the instances are not in TLS, can I use the following ?

private __gshared void[...] store;

I then need to be sure that the objects are instantiated at compile time.
Will Emplace do the trick ?


May 28, 2016
On 05/28/2016 10:34 AM, Mike Parker wrote:
> On Saturday, 28 May 2016 at 05:30:26 UTC, chmike wrote:
[...]
>> Is a static const Category c variable a TLS variable ?
>
> Yes. All variables are TLS unless explicitly marked with __gshared or
> shared.

I don't think that's true.

----
import core.thread;
import std.stdio;

int m;
const int c;
immutable int i;

void main()
{
    printAddresses();
    new Thread(&printAddresses).start();
}

void printAddresses() { writeln(&m, " ", &c, " ", &i); }
----

Prints (for example):
----
7F554F9E1710 695FF0 695FF4
7F554EDDA5D0 695FF0 695FF4
----

So there are two different `m`s, but the `c`s and `i`s have the same address on both threads. Seems to me that `m` is in TLS, but `c` and `i` are not.
« First   ‹ Prev
1 2