Translating C const
Jonathan M Davis
jmdavisProg at gmx.com
Fri May 25 16:17:19 PDT 2012
On Wednesday, May 16, 2012 10:24:55 Jacob Carlborg wrote:
> On 2012-05-16 09:00, Jonathan M Davis wrote:
> > Probably true. But also, if you're talking about a const pointer to a
> > mutable value, the constness of the pointer is actually irrelevant to the
> > caller. The pointer will be copied when the function is called, so it
> > doesn't matter on whit whether the pointer itself is const or not. What
> > matters is whether what's being pointed to is const or not. So, if you
> > have a function which takes a const pointer to a non-const value, then
> > that's essentially identical to one that takes a non-const pointer to a
> > non-const value as far as the declarations go - and for declaring
> > extern(C) functions for use in D, that's generally all you care about.
> >
> > - Jonathan M Davis
>
> Ok I see, thanks. Is that true for fields in structs and global
> variables as well?
Well, the reason that it's not an issue at all with function parameters where
it's the pointer which is const is that the const portion is being copied.
With a struct being passed to a function as an argument, anything which is
directly const in the struct doesn't have to stay const when passed (it's just
the indirect stuff which would be - pointers and references - though having a
reference as a member variable is a bit evil). However, if that same struct
can be passed around via a pointer, then those member variables would have to
be const.
I'm not sure that it's possible to generically constify C structs for D
correctly. If you just use D's const on const member variables, then you won't
be able to mutate what's pointed to by pointers which were const but pointed
to mutable data in the C definition. In many cases, that wouldn't be an issue
at all, but depending on what you needed to do in D, it would be. On the other
hand, if you just didn't use const at all, then you _could_ mutate what needed
to be mutated, _and_ it would be perfectly legal per C, because it would be
the equivalent of casting away const in C, but if the C stuff really did treat
it as const, and the D code mutated it, that could cause bugs.
Sadly, the most correct thing would probably be to error on the side of _not_
making extern(C) stuff const, because mutating what should have been const is
legal in C (so not having it const in D and then mutating it wouldn't violate
C's guarantees at all), whereas if you make it const, the D code is free to
assume that the C code _isn't_ going to mutate it, and since the C code _can_
cast away const (or may be dealing with non-transitive const such that it can
legally mutate some of the object), then making it const when C doesn't
consider it const could result in D incorrectly optimizing stuff. Of course,
since C can always cast away const regardless, having D call _any_ C functions
which use const stuff (even if it's transitively const in C as well) could
result in const stuff being mutated. However, if D were to just assume that
const optimizations can't be done when dealing with extern(C) functions (I
don't know if it does or not), then using const more heavily wouldn't be as
big a deal.
Anyway, I suppose that that's not terribly conclusive, but the lack of ability
to have non-transitive const declarations is a bit of a problem when dealing
with extern(C) functions given that it has behaviors that D _doesn't_ have. As
far as I can see, whether constifying the whole thing or making it all mutable
makes more sense really depends on what the C function is doing and how it's
called, which naturally doesn't go well with a tool like you're creating.
You'll probably have to go with what is _least_ likely to cause bugs and then
let the programmer adjust it as needed.
- Jonathan M Davis
More information about the Digitalmars-d-learn
mailing list