logical const without casts!
Christophe
travert at phare.normalesup.org
Fri Sep 30 11:51:19 PDT 2011
"Steven Schveighoffer" , dans le message (digitalmars.D:145850), a
> As long as you assume the context pointer is part of the state of the
> aggregate, then yes. But I don't see it that way. The context pointer is
> part of the state of the delegate, and the delegate reference itself is
> the same as a function pointer -- it's not affected by immutable or const.
That is actually where our opinions differ.
I wouldn't blame the langage for choosing you proposal rather than mine.
I just personnaly think my proposal in more in the spirit of the
langage, and offer more guarantees when dealing with immutables.
> This also doesn't work:
Indeed. The compiler should not allow the implicit conversion of
globalFoo to immutable.
> class Foo
> {
> this(ref int _i) { dg = () { return _i; } }
> ref const(int) delegate() const dg;
> ref const(int) i() const { return dg(); }
> }
>
> int globalInt;
>
> immutable Foo globalFoo = Foo(globalInt);
^ error: can't cast ref int _i to immutable ref int in immutable
Foo.this()._delegate_1.
> void thread1()
> {
> writeln(globalFoo.i);
> }
>
> int globalBar()
> {
> spawn(&thread1);
> globalInt = 5; // does thread1 see this change or not?
> }
> It looks like any time you call a delegate member of an immutable object,
> it could access a context pointer that is not implicitly shared.
Not if the compiler cares to check the delegate context is indeed
immutable when the immutable delegate is created. It is not much more
complicated than if Foo contained an explicit pointer to i instead of a
delegate
> Not to mention, what the hell does a const function mean for a delegate
> literal? The context pointer is the context of the function, not an
> object. How does that even work?
Internally, it is a pointer to a structure containing the delegate
context that is generated by the compiler. If the delegate is const, the
pointer should be a const pointer. If the delegate is immutable, it
should be an immutable pointer, and the compiler as to check there is no
mutable version of that pointer before making an implicit cast.
> What is probably the "right" solution is to disallow implicit immutable
> objects which have a delegate. This means:
>
> a) you cannot initialize a shared or immutable such object without a
> cast. This means the line immutable Foo globalFoo = new Foo(globalInt) is
> an error without a cast.
Agreed, but with my proposal, you can have an immutable Foo, if the
delegate context pointer can be cast to immutable.
> b) Any time you have a const object that contains a delegate, it can be
> assumed that the object is not shared.
If the object is const, you have no guarantee that the objet is not
shared, making an exception for object containing a delegate is quite
wierd.
> And then we avoid dealing with the const delegate issue altogether.
Dealing with this issue could be very useful for multithreaded
applications.
>> With my proposal, you can very easily keep an immutable reference in a
>> const delegate. The delegate will just not be callable if its
>> function pointer is not const with regard to the context pointer.
>
> You can also very easily keep a mutable reference in a const delegate
> inside an immutable object. It's not mutable through the delegate, but
> it's also not immutable.
No, the compiler should check the delegate context is immutable when
making the cast to immutable.
I admit you have found a very interesting corner-case for my proposal
that I had not thought of that case. Thank you for that. I think the
proposal passed the test (until now).
More information about the Digitalmars-d
mailing list