Head Const

Jonathan M Davis via Digitalmars-d digitalmars-d at puremagic.com
Mon Feb 15 22:04:42 PST 2016


On Monday, 15 February 2016 at 22:48:16 UTC, Walter Bright wrote:
> rears its head again :-)
>
> Head Const is what C++ has for const, i.e. it is not 
> transitive, applies to one level only. D has transitive const.
>
> What head const will do for us:
>
> 1. make it easy to interface to C++ code that uses const, as 
> currently it is not very practical to do so, you have to resort 
> to pragma(mangle)
>
> 2. supports single assignment style of programming, even if the 
> data is otherwise mutable
>
> The downside is, of course, language complexity.

Straight up head-const is utterly useless IMHO. That's what Java 
has. C++ has something far more complicated where any individual 
piece (or pieces) of a pointer type can be declared const without 
necessarily making the whole thing const. So, _that_ is what we'd 
need to interact with C++, and it's a downright ugly feature 
IMHO. Tail-const has some value, because it allows you to refer 
to a const object with a mutable pointer or reference, whereas 
head-const just makes things ugly. So, if it weren't for 
interacting with C++, I would give a resounding "no" to this. 
It's not even vaguely worth the complexity.

As for interoperability with C++, I don't know. Previously, you 
stated that we weren't going to do things like support 
interacting with C++ templates (aside from specific 
instantiations which weren't typed as templates), because it 
would mean putting a C++ compiler into D, which you didn't want 
to do. But increasingly, it seems like you're heading in the 
direction of doing that in an attempt to be able to have 
fantastic C++ interoperability. On the one on hand, that seems 
great, since being able to have your C++ code work with your D 
code is great, but on the other, it seems like it's going to make 
it so that D is contaminated by a lot of extra C++ muck just to 
be able to interoperate. At some point, we either need to decide 
that we're just not going to interoperate with C++ in some manner 
and lose out on some capability, or we're going to need to fully 
interoperate with C++ and pretty much put a C++ compiler in the D 
compiler, and I'd prefer that we didn't go that far.

In this particular case, doesn't this really just come down to 
mangling? It's undefined behavior in D to mutate a const object 
(even if it was constructed as mutable), so we can't just slap D 
const on C++ types and have that work, since the C++ code could 
legally mutate the object. But since C++ considers it defined 
behavior to mutate a const object by casting away const (or at 
least it does in all but some very specific cases), can we just 
get away with the D code treating D const as mutable? If so, then 
it's purely a matter of mangling. And for that, we could do 
something like add @cppconst or cppconst that the compiler 
recognizes and which is only valid in extern(C++) declarations. 
It would unfortunately have to be more than a simple attribute, 
because it would have to apply to parts of a parameter's type 
like C++'s const does (instead of the whole type at once), but if 
it were implemented such that it was just something that went on 
the extern(C++) function parameter types (or return types) for 
mangling purposes, and the D code just treated it as mutable, 
then it would at least restrict the muck to extern(C++).

Now, that does have the downside that the D code has no 
protection against mutating a C++ object that the C++ code marks 
as const (whereas while the C++ code can mutate, you at least 
have to cast away const or use the mutable keyword first), but 
that seems a whale of a lot better to me than trying to add 
non-transitive const to D.

- Jonathan M Davis


More information about the Digitalmars-d mailing list