How do I copy struct having immutable pointer member when enabled DIP1000?
ag0aep6g
anonymous at example.com
Mon Aug 31 05:46:45 UTC 2020
On 31.08.20 06:24, outlandkarasu wrote:
> I thought that I cannot make non-scope `ref` parameters from `scope`
> array references.
> But I found It allowed currently.
[...]
> enum Currency : string {
> USD = "USD", EUR = "EUR", GBP = "GBP", JPY = "JPY",
> }
>
> struct Instrument {
> Currency bid;
> Currency ask;
> }
>
> struct Price {
> Instrument instrument;
> ulong value;
> }
[...]
> void update(scope const(Price)[] prices) scope
> {
> foreach (price; prices)
> {
> update(price);
> }
> }
>
> // I thought price parameter need `scope` when called by scoped
> array elements.
> // But it can remove `scope` attribute.
> void update( /* scope */ ref const(Price) price) scope
> {
> if (minPrice.isNull || price.value < minPrice.get.value)
> {
> minPrice = price;
> }
> }
`ref` kind of implies `scope` [1]. You don't need to type it out. When
you do type out `scope ref const(Price)`, the `scope` actually doesn't
apply to the `ref` but to the pointers in `Price` (whereas the `scope`
in `scope const(Price)[]` applies to the pointer of the array).
So you don't need `scope` on the `price` parameter because you're taking
it as a `ref`. You would need `scope` if you were taking it as a pointer
(`scope const(Price)* price`).
By the way, semantically there isn't any reason to take `price` as
either `ref` or pointer. You can just as well take it by value, since
you're making a copy of it anyway with `minPrice = price` (and you also
make a copy earlier with `foreach (price; prices)`).
[...]
> I also found a worried point that I can take non-scope pointer from
> non-scope `ref` parameter in DMV v2.093.1.
>
> --------
> class MinPointerRecorder
> {
> @nogc nothrow pure @safe:
>
> void update(scope const(Price)[] prices) scope
> {
> foreach (price; prices)
> {
> update(price);
> }
> }
>
> void update( /* scope */ ref const(Price) price) scope
> {
> if (!minPrice || price.value < minPrice.value)
> {
> // Is this DIP1000 BUG?
> // When without DIP1000, reported compile error.
> // Error: cannot take address of parameter price
> minPrice = &price;
> }
> }
>
> const(Price)* minPrice;
> }
> --------
Definitely a bug, yes. Reduced test case:
----
class MinPointerRecorder
{
int* minPrice;
void update(ref int price) @safe
{
minPrice = &price; /* Should not compile. */
}
}
void main() @safe
{
auto r = new MinPointerRecorder;
() { int mp = 42; r.update(mp); } ();
() { ulong[1000] stomp = 13; } ();
import std.stdio: writeln;
writeln(*r.minPrice); /* Prints "13". */
}
----
I don't think this is in Bugzilla yet. Please file an issue. Or let me
know if you want me to do it.
https://issues.dlang.org
[1] I'm not exactly sure how it works. As far as I know, it's not
documented anywhere.
More information about the Digitalmars-d-learn
mailing list