std.digest toHexString

Adam D. Ruppe via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Mar 16 10:50:45 PDT 2017


On Thursday, 16 March 2017 at 17:20:45 UTC, H. S. Teoh wrote:
> I'm not convinced casting static array to immutable is OK. 
> Check this out:


You aren't casting static array to immutable there, it is being 
implicitly sliced AND cased to immutable.

What I mean is:

char[32] s;
immutable(char)[32] i = s; // that is sane, it copies anyway
immutable(char[32]) i2 = s; // also sane


That's an implicit cast to immutable, but since both sides are 
still static arrays, it is no different than

int a = 0;
immutable b = a; // ok

Value types can be copied in and out of immutable implicitly 
without worry.

It is when they become a reference type that things go wrong. 
And, in isolation, the compiler knows this too:

immutable(char)[] i = s; //  Error: cannot implicitly convert 
expression (s) of type char[32] to string


But when you put it behind a function like you did, two things 
happen:

1) it sees it is a return value by value, and thus unique... so 
it is safe to cast to immutable

char[32] func() {
         char[32] a;
         return a;
}

void main() {
      immutable(char[32]) a = func(); // that's fine! it is copied 
so it is immutable
}

but 2), it is also willing to slice it:

char[] b = func(); // legal under current rules... but insane

and 3) knowing it is a slice of unique data, it allows it to be 
casted just like:

pure char[] foo() { return []; }

string implicit = foo(); // fine - pure slice must be unique due 
to purity rules, and unique mutable can become immutable


Combine all that and we get:

char[32] func() { }

1) char[] implicitlySliced = func(); // stupid, but allowed by 
language rules
2) immutable(char)[] implicitly immutable = impliciltlySliced; // 
ok, because it is unique...
3) crashing in bug city.





Of all those rules, preventing the implicit slice is the easiest 
fix:

string s = func(); // error, CAN implicitly cast from char[32] to 
immutable(char[32]) but can NOT implicitly cast from static to 
dynamic

Being a unique value, casting to immutable is perfectly sane.

immutable(char[32]) s = func(); // makes sense
string s2 = s; // nope, if you really meant it, write `s[]`

But the caller should be aware of when a reference is taken.

string s = func()[]; // I'd allow it, at least the user wrote 
`[]` meaning they realized it was stack data and presumably knows 
what that means about the slice's lifetime


More information about the Digitalmars-d-learn mailing list