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