Transferring 32 bits

Adam D Ruppe destructionator at gmail.com
Thu Aug 25 12:40:57 UTC 2022


On Thursday, 25 August 2022 at 12:18:19 UTC, Salih Dincer wrote:
>   char[size] bytes;
>
>   alias toString this;
>   string toString() const
>   {
>     scope res = [ cast(string) bytes ];
>     return res[0];
>   }

This code is completely wrong. You're improperly casting mutable 
and limited lifetime data to string, then returning it. And that 
scope res has no reason to exist; the code is identical to just 
`return cast(string) bytes;` which the compiler will slice for 
you  - taking a pointer of it - then you return that slice with a 
new type.

So this is returning a pointer to a local variable which is 
liable to cease to exist as soon as the function calling it 
returns...

> string foo(char[size] bytes)
> {
>   scope res = S(bytes);
>   return res.toString(); // problem here
> }

...which is exactly what you're doing here. Those bytes inside S 
live on the stack of this foo function. You return a pointer to 
them, then the foo function returns and those bytes on the stack 
cease to exist (actually reused memory but same thing 
conceptually) yet you keep the reference.


>   auto m = S(text);  // test ok
>   assert(m == text);

this only works because m still exists at the point of the 
assert, once there's another function involved the stack memory 
is gone.


What you want to do instead is either `.idup` the bytes or make 
your toString do a `void delegate(in char[]) sink` and you pass 
the bytes to the sink casting to char[].


More information about the Digitalmars-d mailing list