const and immutable member variables in classes

H. S. Teoh via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue Feb 2 18:14:50 PST 2016


On Tue, Feb 02, 2016 at 05:49:00PM -0800, Jonathan M Davis via Digitalmars-d-learn wrote:
> On Tuesday, February 02, 2016 14:48:03 Ali Çehreli via Digitalmars-d-learn wrote:
> > const and immutable members make structs non-assignable:
[...]
> > That's why I've been avoiding them altogether. However, considering
> > that there is no default-assignment for classes, there is no problem
> > with using const or immutable members with classes, right?
> 
> Default initialization isn't really the issue. It's assignability in
> general. Even if you @disabled default initialization in a struct,
> then having a const or immutable member would be annoying, because you
> couldn't assign it another value later. But in any case, no, classes
> don't have that problem (at least not normally), because you don't
> assign to them. You just assign to their references. So, you don't
> normally run into an issue where you're trying to overwrite the state
> of a class object and aren't able to.
[...]

In general, I find const/immutable members more of a pain than anything
else. Such aggregates are extremely cumbersome to work with, and
besides, I've yet to come up with a conceptually-clean mental model of
just what kind of semantics exactly an aggregate with a const/immutable
member "ought" to have.

*Reference* members to const/immutable data make sense -- these include
string members, for example, as immutable(char)[]. It's not a problem
because the reference itself is mutable, just not what it refers to.

It's also not a problem when the entire aggregate is const or immutable,
e.g., when passing by const to a const member, for example. By
transitivity, it's clear that the entire aggregate is const / immutable,
so every member is also transitively so.

But when a member itself is const or immutable, things become really
icky. A mutable instance of a struct with a const member is in a weird
mixed state of being partially mutable and partially not. You can never
create an instance of the struct that's fully mutable, so even when
given a mutable instance, you can't overwrite it, you can't assign to
it, etc..

It's also unclear what guarantee the const/immutable member is supposed
to provide.  In the case of an argument to a function, it's clear that
const means the callee promises not to modify, and immutable means the
caller (and callee) promise never to modify. But what promise does a
const/immutable member give? That nobody can ever modify, except this
only applies to that member and the rest of the aggregate may still be
mutable? It's rather unclean semantics that leads to all sorts of
needlessly convoluted cases, with hard-to-grasp results, and it's hard
to think of a use case that requires such a construct, that can't be
done some other way.


T

-- 
Любишь кататься - люби и саночки возить. 


More information about the Digitalmars-d-learn mailing list