Re: is const necessary in eg int compar(const void *, const void *)



Tim Rentsch said:

Richard Heathfield <rjh@xxxxxxxxxxxxxxx> writes:

Nate Eldredge said:

<snip>

So therefore it would be good practice in functions accepting `const
void *' arguments to assign to a temporary pointer of the appropriate
type, rather than casting, in order to preserve the usefulness of
const.

I'm of the opinion that it's always possible, and usually preferable, to
avoid casting.

Casting is necessary for converting pointers to function. OTOH,
converting pointers to functions hardly ever arises.

It is therefore possible to avoid casting by avoiding converting pointers
to function! But yes, I had overlooked that issue (and one other - see
below).

Converting between arithmetic types is always possible without
casting, by simple assignment.

Right. It was arithmetic types that I mostly had in mind.

Conversion between integer types and pointer types requires
casting, except that a pointer may be assigned to a _Bool.

In code that is intended to be portable, one would wish to avoid converting
between integer types and pointer types anyway - but that's the other
issue I overlooked in making my over-general claim.

Any object/incomplete pointer type may be converted to any other
object/incomplete pointer type without casting. Exercise for
the reader: how can a (const int *) be converted to an (int *)
without casting?

I'm afraid I'll have to pass. Do you have any picture questions? :-)

IMO casting is preferable when avoiding it would introduce one or
more temporary variables solely to avoid having to cast,
especially if used only once.

I nearly agree. I think I do agree if you lose the "especially". For
example, I think this:

printf("%p\n", (void *)p);

is preferable to:

void *t = p;
printf("%p\n", t);

but on the other hand I think this:

int by_age(const void *vsl, const void *vsr)
{
const struct s sl = vsl;
const struct s sr = vsr;
return (sl->age > sr->age) - (sl->age < sr->age);
}

is preferable to:

int by_age(const void *vsl, const void *vsr)
{
return (((const struct s *)vsl)->age > ((const struct s *)vsr)->age) -
(((const struct s *)vsl)->age < ((const struct s *)vsr)->age);
}

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
.



Relevant Pages

  • Re: modifying const qualified object indirectly
    ... through a const struct pointer. ... const-ness) are correct generally depend on the qualification of the definition ... void flip ...
    (comp.lang.c)
  • Re: Maps, filters and accumulators
    ... void pointer they get back to a pointer to the appropriate type of data. ... int(*compar)(const void *, const void *)) ... avoid having to do all that work (either by getting a code generator to ...
    (comp.lang.c)
  • Re: Why is the kfree() argument const?
    ... void foo(const int *x); ... Invalidating the pointer in free is rather noticeable. ... Given that const certainly does not mean that no one else ...
    (Linux-Kernel)
  • Re: modifying const qualified object indirectly
    ... My gut feeling says it is - and I ... through a const struct pointer. ... void flip ... it is the pointer variable f which is const-qualified. ...
    (comp.lang.c)
  • Re: Proper way to do casts while avoiding aliasing issues
    ... enlightening response. ... The 16-byte pointer currently contains garbage ... const qualifiers should not affect the underlying representation, ... Remember that, except for "void *", we said that pointers were all ...
    (comp.lang.c)