[Issue 24793] Allow implicit conversion of const pointers to void*

d-bugmail at puremagic.com d-bugmail at puremagic.com
Thu Nov 21 04:08:31 UTC 2024


https://issues.dlang.org/show_bug.cgi?id=24793

--- Comment #4 from Jonathan M Davis <issues.dlang at jmdavisProg.com> ---
(In reply to Dennis from comment #3)
> (In reply to Jonathan M Davis from comment #2)
> > Also, at present, the implicit conversion from a mutable pointer to void* is
> > considered @safe - e.g.
> > 
> > ---
> > void main() @safe
> > {
> >     int* i;
> >     void* v = i;
> > }
> > ---
> > 
> > whereas it would be completely inappropriate to consider it memory safe if
> > const is implicitly removed in the process. So, even if we did add such an
> > implicit conversion, it would need to be @system.
> 
> No it wouldn't, unless you can actually demonstrate how it would result in
> memory corruption.

Casting away const in general is supposed to be @system, because it's making it
so that it's in the programmer's hands to not violate the type system, and it
should need @trusted to indicate that the programmer is claiming that they've
verified that the code doesn't violate the type system.

While void* is so limited to the point that it's essentially useless on its
own, and any function you call with it that could actually do anything
interesting with it would need to be @system anyway, all it takes is one layer
of function calls in between, and you have a situation where the void* code has
been validated for correctness under the assumption that the data is mutable
but which is completely divorced from the code where the conversion to void*
occurs. And right now, the assumption that the void* pointed to mutable data
would be correct unless the programmer had cast away const elsewhere using a
cast that was @system. But with your proposed change here, it would become
possible to pass a non-const pointer to an @trusted function - or to an @safe
function which calls @trusted function or however many layers happen to be in
between - which operates on void* under the assumption that the data is
mutable. So, you have an @safe implicit cast resulting in memory corruption in
@trusted code that had no reason to expect that it would ever have to worry
about operating on const data.

IMHO, we should never be implicitly removing const when any indirections are
involved - _especially_ when the code being given the data has to be @trusted
and be careful with the assumptions that it makes. It's just a recipe for
disaster. And even if the code being called doesn't happen to mutate its data
today, it could quite legally be changed to do so tomorrow with the full
expectation that it's dealing with data that's mutable, because that's what the
type system is telling it what it has.

In addition, we should be very conservative about deciding that something is
@safe, especially since all it takes is one assumption about the current
situation to change, and it might cease being memory-safe - and that's
especially likely to happen when we keep trying to widen what's considered
@safe. It's just too easy to accidentally introduce a corner case - or outright
miss a corner case in the initial analysis - where the code isn't actually
memory safe. We already occasionally find holes in @safe that we missed, and as
Rikki points out in https://issues.dlang.org/show_bug.cgi?id=24866, we're
risking memory safety issues with stuff like this with the introduction of
language features such as placement new.

--


More information about the Digitalmars-d-bugs mailing list