copy must be const?!?

Dom DiSc dominikus at scherkl.de
Mon Jul 29 13:13:45 UTC 2024


On Friday, 26 July 2024 at 10:04:45 UTC, Jonathan M Davis wrote:
> On Friday, July 26, 2024 2:17:21 AM MDT Dom DiSc via 
> Digitalmars-d-learn wrote:
>> If you are not able to construct a mutable copy of a type, why 
>> on earth are you handing it over by value?!?
>
> Why not?

Because you can't make a mutable copy?

> Structs are [...] often pseudo-reference types. [...]
> such types can often work just fine with const copies, because 
> the data that's shared between objects is const or immutable.

Then declare the template to take a const parameter.

>> ```d
>> immutable MyNonCopyableType x;
>> MyNonCopyableType y = x; // compile error?
>> ```
>
> If you can't get a mutable copy of MyNonCopyableType, then yes, 
> you'll get a compiler error.

This is why you should get the same error, if the compiler cannot 
create a mutable parameter-by-value copy.

> In D, const is pretty much cancer, honestly. You do _not_ want 
> to use it for generic code if you can possible avoid it,

Why? In a template that guarantees not to modify a parameter by 
declaring it const, what bad can happen?

> because many, many types do not work with it at all.

At least reading it should never be a problem. And nothing more 
one want to do with a const parameter.

But I don't see your problem. I'm taking about situations where a 
const instance of a type IS ALREADY THERE (which will never be 
the case with any of your problematic types), and I want to have 
a mutable copy of them.
So if the compiler would discard the const from parameters that 
are anyway never const, that's a NOP. All is fine.

On the other hand if there is a const object, that should be an 
object of a type that indeed CAN provide mutable copies. This is 
also fine.

So, where is the problem if the compiler drops "const" from the 
by-value copy of a parameter?

> in situations where a type can be logically const (or which 
> could be const in C++), it cannot be const in D, because D's 
> const is simply too restrictive.

Sorry, but if a type is "logically const" (like a range) and you 
read it and thereby change it's internal state, then the template 
that guaranteed not to modify a parameter is very likely to 
destroy this internal state, and so you are much better of if 
this doesn't compile beforehand.

Some templates are simply not meant to work with all kinds of 
user defined types.

> If you declare the parameter to be const, then there are a lot 
> of types that won't work with the template.

Fine. If I can change the internal state via read-functions, I 
don't want to work with that bogous type. If my intention is not 
to modify an object, I'm perfectly ok that I can't use may of 
that fake-const types functions.

> On top of that, in many cases, getting a mutable copy would 
> give you completely incorrect behavior - e.g. if a range is a 
> range over a container, you need that range to point to the 
> elements in the container, and if the range refers to those 
> elements as const, then getting a mutable copy of those 
> elements would mean that they're no longer necessarily the same 
> elements which are in the container (they might be at the point 
> that the copy is made, but that won't necessarily stay true, 
> whereas it would if the elements aren't copied).

Ranges are a bad example, because they really cannot be const. 
They are completely unusable in a function not modifying them, 
because reading them is using them up. So a function taking a 
range as parameter indeed cannot guarantee not to modify it (at 
least not if it reads that parameters data at all).

> It's also the case that a lot of code simply avoids using const 
> altogether with user-defined types

Fine. Then you won't run into the problem I have. And indeed, as 
you weren't aware of this problem is an indicator that you are 
not really using const.

> Most anyone who tries to use D's const like you would in C++ 
> eventually stops, because D's const is simply too different 
> from C++'s const for that to work.

No, so far the C++ code I converted to D is working fine. And it 
is heavily using const - but it uses it correct, despite C++ 
doesn't enforce that. Maybe I never used C++ the way it was 
meant?!?

> And that's especially true with templated code, since if it has 
> to work with a large range of types, types which don't work 
> with const are going to be on the list.

Nope. Constraints work very good in guaranteeing that such types 
are NOT on the list of types the template is working with.

> On top of that, some common D idioms (e.g. ranges) can't work 
> with const, because they require mutation (a range can have 
> const elements, but the range itself cannot be const).

Jup. If a template takes a range, it should not take it const.
But I also won't take a range by value. As whatever I do will 
modify the range, why should I pretend to work on a copy of it? 
Take it by ref!



More information about the Digitalmars-d-learn mailing list