const attribute makes whole element const?
Jonathan M Davis
jmdavisProg at gmx.com
Sun Sep 9 17:29:38 PDT 2012
On Monday, September 10, 2012 02:05:08 Namespace wrote:
> I had never problems with that in C++.
> If I have members which are const because they are assigned only
> one time and needs no other assignment, why should I declare this
> member not as const?
>
> In the example I know exactly that I assign only one time a name
> to this struct, so why I should not declare it as const?
>
> Other example: you have a unique birthday date. This is const you
> cannot change it like a name or a telephone number. So if you
> have a Person struct which holds any data of a single people, you
> won't declare the date as const? I would. And I had expected that
> this is normal behaviour.
Once something is const, you _cannot_ change it. C++ lets you cast away const
and mutate things, meaning that they aren't really const. D doesn't allow
that. Casting away const and mutating a variable is undefined behavior. D has
no mutable keyword. D's const is also transitive, meaning that once something
is const, everything within it is const (e.g. once you declare a container
const, _every_ element inside it is const as well). So, any and all operations
which would involve mutating a const variable are illegal - including mutating
something which a const variable refers to, since _everything_ it refers to is
const.
With structs, this has the effect that once one member variable is const, you
can never again reassign the whole thing. You can assign to its non-const
members but not the whole thing.
In this particular case, you're dealing with an AA. Depending on the AA's
implementation, it should be possible to initialize tests[4] and then never
assign to it again, but that's problematic due to rehashing (hash table's
_need_ to be able to move objects around), and the current AA implementation
is fairly poor anyway. So, it ends up default-initializing the value and
_then_ assigning it, which doesn't work if you can't reassign the value. It
shouldn't be doing that. It's a bug, and it causes problems with stuff like
exceptions. For instance, if you have
aa[key] = func();
and func throws, then aa ends up with a default-initialized value at key:
http://d.puremagic.com/issues/show_bug.cgi?id=3825
druntime's AA implementation needs a fair bit of work. H.S. Teoh is working on
a better implementation, but who knows when we'll have it. We just have to put
up with buggy corner cases until then unfortunately (though at least AA's work
just fine most of the time).
I don't know if this particular use case will ever work though, because it
makes it so that the struct can never be reassigned, and I'm not sure that
it's at all reasonable for an AA to never be able to reassign its values. Yes,
initialization should work (unlike now), but rehashing needs to move values
around, and hash tables have to be able to rehash when they get full enough,
meaning that being able to reassign elements will probably be required.
- Jonathan M Davis
More information about the Digitalmars-d-learn
mailing list