| |
| Posted by H. S. Teoh in reply to Alexandru Ermicioi | PermalinkReply |
|
H. S. Teoh
Posted in reply to Alexandru Ermicioi
| On Fri, Apr 08, 2022 at 01:50:01PM +0000, Alexandru Ermicioi via Digitalmars-d wrote:
> On Wednesday, 6 April 2022 at 09:41:52 UTC, RazvanN wrote:
> > ...
> It may be a dumb and already discussed question, but what's the problem of making rc counted structs mutable only?
>
> In this way, you won't have the dilemma of circumventing the immutable/const system, to just increment the counter, or any metadata.
>
> Note: the payload of rc struct, may be const or immutable if needed.
[...]
In theory, this would IMO be the right approach. However, it does hamper usability. For example, you could no longer write:
auto myFunc(in RC!Data data) { ... }
but you'd have to write instead:
auto myFunc(RC!(const(Data)) data) { ... }
because RC!... has to remain always mutable.
Some of the nice implicit conversions would also no longer work as
desired, e.g., RC!Data would not implicitly convert to RC!(const(Data)),
where with GC'd data, Data* implicit converts to const(Data)*. This
asymmetry makes metaprogramming harder to work with RC.
Things get worse once you have nested structures, e.g.:
struct SubData {...}
struct S {
RC!SubData data;
}
Now you couldn't pass S to anything that takes const, because transitivity of const would force RC!SubData to be const(RC!SubData), which breaks the refcounting mechanism. Basically, once you have RC!xxx in any subpart of your data structure, it "reverse-infects" the entire data structure with mutable, because you can no longer use const on any containing part of the structure, since it would break RC.
Basically, unless you have a hack like __mutable, you basically have to throw out const/immutable entirely from your data structures once any part of it involves RC.
T
--
Век живи - век учись. А дураком помрёшь.
|