Why does this not compile?

Steven Schveighoffer schveiguy at yahoo.com
Tue Mar 6 16:19:27 UTC 2018


On 3/6/18 10:00 AM, Simen Kjærås wrote:
> On Tuesday, 6 March 2018 at 13:56:30 UTC, Steven Schveighoffer wrote:
>> On 3/6/18 8:42 AM, Simen Kjærås wrote:
>>> unittest {
>>>      int i = 0;
>>>      struct S {
>>>          int n;
>>>          void fun() const {
>>>              i++;
>>>          }
>>>      }
>>>      const S s;
>>>      assert(i == 0);
>>>      s.fun();
>>>      assert(i == 1);
>>> }
>>
>> That, I would consider a bug. If it's not, then definitely, you should 
>> be able to implicitly cast to/from const.
>>
>> So a bug report is in order. It should be decided one way or another 
>> -- either the context pointer is part of the struct type or it isn't.
> 
> immutable throws a wrench in the works for the idea that the context 
> pointer is part of the struct. Consider the exact same example, but with 
> immutable(S) instead of const(S). IMO, this indicates the context is not 
> part of the struct (though the context *pointer* arguably is).
> 
> And just in case anyone doesn't immediately see how even disallowing the 
> above would not solve the immutable problem:
> 
> unittest {
>      int n = 0;
>      struct S {
>          int fun() const { return n; }
>      }
>      immutable S s;
>      assert(s.fun == 0);
>      n++;
>      assert(s.fun == 1); // Not so immutable now, are you?
> }

That's not a demonstration of breaking immutability. counter-proof:

struct S
{
    static int x;
    int fun() const { return x; }
}

immutable S s;
assert(s.fun == 0);
S.x++;
assert(s.fun == 1);

In other words, if the struct can access the data considered "outside 
it's instance", then it it can return it, change it even.

However, this is not a question that has been answered yet. The compiler 
clearly treats the context pointer as part of the instance in some 
cases, and not part of the instance in other cases.

Note that if the decision comes down that the context pointer is part of 
the instance, even *creating* an immutable S should be disallowed, as it 
clearly allows both mutable and immutable references.

> Interestingly, replacing 'const' with 'immutable' on fun gives a 
> compilation error: "immutable function 'foo.__unittest_foo_1_0.S.fun' 
> cannot access mutable data 'n'".

Wat... This is like taking both sides at once (it's both part of the 
instance and not part of the instance).

> This seems even weirder to me, but can certainly be taken as evidence in 
> favor of your view. The same error message does *not* show up if n is 
> instead a global variable.

This is very broken. And it needs attention.

-Steve


More information about the Digitalmars-d mailing list