On Thursday, 25 September 2014 at 13:37:52 UTC, Steven
Schveighoffer wrote:
On 9/25/14 9:00 AM, monarch_dodra wrote:
On Thursday, 25 September 2014 at 12:46:01 UTC, Steven
Schveighoffer wrote:
On 9/25/14 5:47 AM, monarch_dodra wrote:
I was playing around with how T.init works. And I think I
may have found
a type loophole.
Given that you may initialize a pointer member to the
address to a
static global:
//----
__gshared int a = 0;
struct S
{
int* p = &a;
}
//----
Then, in theory, any variable, be they mutable or const, are
initialized
to T.init:
//----
void main()
{
immutable S s;
}
//----
This is an issue, because I now have an immutable pointer
that points to
mutable data:
//----
immutable S s = S.init;
immutable int* p = s.p;
assert(*p == 0); //OK
a = 5;
assert(*p == 5); //OK
//----
So this violates the type system...
The question here is:
Is this "legit" code? At what point do you think my code
should have
been rejected?
It should be rejected. The declaration of s (the variable)
should be
the trigger, since it casts the pointer to immutable.
Please file a bug report.
-Steve
Hum... So that means certain types just *can't* be initialized
(as
immutable) at all?
I wouldn't say that:
immutable s = S(null);
But clearly, any code that results in an immutable pointer to
mutable data without casts is incorrect. We should start by
outlawing such code, and if there are ways we can carve out
certain usages, we can do that.
-Steve
Hum... right, but I meant "T.init" itself would not be valid. As
in:
alias T = immutable(S);
T t = T.init; //Illegal?
This might be a borderline case, but I kind of figured that that
piece of code was the *only* one that was universally valid in
generic code.
The context was this pull request:
https://github.com/D-Programming-Language/phobos/pull/2172
This sucks...