well, yes, but I listed that they could add this as well.
probably most C++ code wouldn't notice the change.
I should have been more clear about my point here: I was trying to say
that the only reason this definition of NULL is unacceptable to C++ is
because of the lack of the implicit conversion from void*. Given that
conversion, there would be no other barrier in C++ to using ((void*)0)
for NULL.
possibly, the change could be limited to 'extern "C"' code or similar
(and/or could be ignored in cases of templates or overloading, or at
least be a lower priority than any other matches).
I think the rules for overload resolution and template type deduction
are complicated enough without introducing a feature that behaves
differently depending on whether or not it interacts with those systems.
There's no such thing as 'extern "C" code': extern "foo" is a *linkage
specification* whose sole purpose is to tell the implementation to
engage the ABI machinery appropriate for language "foo".
there are plenty of uses besides malloc, so malloc is just one of many
cases (mmap, memcpy, VirtualAlloc, ...).
or, a biggie:
for any user-defined code which accepts or returns "void *".
Returns, not accepts. The implicit conversion _from_ void* is dangerous,
implicit conversion _to_ void* is perfectly safe type erasure.
for example, to do similar tasks in C++ often requires a larger number
of casts.
could work...
this would break large amounts of C code.
I'll handwave here and claim that's what compiler options are for. Valid
C90 code will always be valid C90 code, I see no reason why a future C20
compiler couldn't be instructed to compile code as C90. Old code will
always be old code, but does that mean that we have to keep on writing
old code forever?
It's already the case that C11 made some C99 features optional: there
may be conforming C11 compilers that refuse to compile some conforming
C99 programs. The kind of change I suggest is quantitatively but not
qualitatively different.
I don't think people on either side would want changes which cause their
existing programs to break and have to be rewritten.
we call this 'void *', where this is nearly the only thing that can
really be done with this type anyways ("void" variables are otherwise
pretty much useless, ...).
I am differentiating between the implicit conversion _from_ any pointer
type and the implicit conversion _to_ any pointer type; I posit that
those two features have unique design intentions and should therefore be
represented by distinct types. C conflates the two ideas in void*, C++
doesn't have the conversion _to_ any pointer type at all, except for
nullptr. (Given how simple it is to make a user-defined type in C++ that
implicitly converts to any pointer type, it's notable that I've never
seen anyone feel the need to do so.)
void* has 2 uses in C:
1. it's the "sink" type to which all other pointer types can be
implicitly converted.
2. it's the "source" type that implicitly converts to all other pointer
types.
and 2 uses in C++:
1. "sink" type just as in C.
2. type-erased pointer that designates _some_kind_ of object about which
nothing is known except its location in memory.
The secondary usage is diametrically opposite between C and C++: one
disallows using a void* for any purpose without a cast, the other allows
you to pass a void* where you would any pointer type without a cast. In
C, I can pass the same void* to fclose, free, strcat, and
hundreds/thousands of other functions without a compiler diagnostic.
Using void* you've effectively opted out of a large part of the type system.
C programmers also often use void* as either a type-erased or generic
pointer but do so purely based on convention and discipline: you will
get no help from the compiler. If an intern jumps into your code the
next day and passes your type-erased pointer to fputs, the compiler will
accept it happily.
yes, but the least impact route would be to just pick up C's "void *"
semantics for this, since C++ code isn't likely to notice, and existing
C code can keep working unmodified.
While it's true that making the language more permissive doesn't impact
the correctness of existing programs, that doesn't necessarily make it
always a good idea. I seriously doubt that the C++ community would ever
accept implicit conversion from void* into the language; the case I'm
attempting to make here is that C shouldn't have that feature either and
likely would not if it was designed afresh today.
Given that preserving the semantics of old code has a higher priority to
the C community than almost any other concern, I think it's unlikely
that we will ever have a C++ that is truly a superset of C. If anything
I think it's more likely that C++ would introduce even more breaking
changes to become _less_ compatible with C.