Reading a string in binary mode
Christof Schardt
csnews at schardt.info
Mon Mar 3 23:11:18 PST 2014
"bearophile" <bearophileHUGS at lycos.com> schrieb im Newsbeitrag
news:qqcdemwimcylaizjyhfg at forum.dlang.org...
> Christof Schardt:
>
>> By "trickery" I meant having to know about things like
>> "import std.exception : assumeUnique" for this basic kind of task.
>
> Your function has signature (you use "ref" instead of "in" or "out"
> because it performs read/write):
>
> void rw(ref string x)
>
> A string is a immutable(char)[], that is a dynamic array of immutable
> (UTF-8) chars. In D a dynamic array is a struct (so it's a value) that
> contains a length of the string (here in multiple of char.sizeof, that are
> bytes) and a pointer to the actual string data. Your function gets a
> string by reference, so it's a pointer to a mutable struct that points to
> immutable chars.
>
> The else branch suggested by John Colvin was:
>
>> else
>> {
>> size_t size;
>> _f.rawRead((&size)[0..1]);
>> auto tmp = new char[size];
>> _f.rawRead(tmp);
>> import std.exception : assumeUnique;
>> x = tmp.assumeUnique;
>> }
>
> This allocated a GC-managed dymamic array of chars (the buffer tmp), and
> loads the data into them:
>
> auto tmp = new char[size];
> _f.rawRead(tmp);
>
> Now you can't just perform:
>
> x = tmp;
>
> D manages the pointer to the dynamic array x automatically, so x can be
> seen as a dynamic array array. But their type is different, x refers to
> immutable(char)[] while tmp is a char[]. In general you can't implicitly
> convert immutable data with indirections to mutable data with
> indirections, because this breaks the assumptions immutability is based on
> (while in D you can assign a char[] to a const(char)[] variable. It's the
> difference between const an immutable). So the "trickery" comes from
> satisfying the strong typing of D. It's the price you have to pay for
> safety and (in theory) a bit of improvements in concurrent code.
>
> assumeUnique is essentially a better documented cast, that converts
> mutable to immutable. It's similar to cast(immutable). D doesn't have
> uniqueness typing so in many cases the D compiler is not able to infer the
> uniqueness of data for you (and unique data can be implicitly converted to
> immutable). But the situation on this is improving (this is already
> partially implemented and merged, and will be present in D 2.066:
> http://wiki.dlang.org/DIP29 ).
>
> when the function you are calling is pure (unlike rawRead) you don't need
> assumeUnique:
>
> import std.exception: assumeUnique;
>
> void foo(out char[] s) pure {
> foreach (immutable i, ref c; s)
> c = cast(char)i;
> }
>
> // Using assumeUnique:
> void bar1(ref string s) {
> auto tmp = new char[10];
> foo(tmp);
> s = tmp.assumeUnique;
> }
>
> // Using the D type system:
> void bar2(ref string s) {
> static string local() pure {
> auto tmp = new char[10];
> foo(tmp);
> return tmp;
> }
> s = local;
> }
>
> void main() {}
>
> Bye,
> bearophile
Great, thanks for this insight.
Christof
More information about the Digitalmars-d-learn
mailing list