tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: why cast to char* through void*



At Fri, 3 Jul 2009 11:59:38 -0400, Thor Lancelot Simon 
<tls%panix.com@localhost> wrote:
Subject: Re: why cast to char* through void*
> 
> On Thu, Jul 02, 2009 at 07:48:50PM -0400, Greg A. Woods wrote:
> > At Thu, 2 Jul 2009 14:59:39 -0400, christos%zoulas.com@localhost (Christos 
> > Zoulas) wrote:
> > > I agree, and lint should be fixed instead of polluting the code with 
> > > linted
> > > comments.
> > 
> > I don't think lint can, or needs to be, fixed in this case though.
> > 
> > I.e. the lint warning is valid in most cases -- this isn't necessarily a
> > safe construct.
> 
> I think more often than not, a cast to (char *) in the modern era where
> we have (void *) as a generic pointer is in fact likely to be intentional
> and safe -- it indicates the programmer really, *really* wanted bytewise
> access to the structure in question.
> 
> I think this is almost certainly why the pointer-aliasing rules, in fact,
> make a special exception for (char *), and so I think lint should, too.

I understand the lint warning as being valid for different reasons.

I.e. here we really are mixing fundamentally incompatible data types in
the same storage object (though it's not a true storage object in the
sense of being associated with a basic type).  Normally I think this
would be considered to be "A BAD Thing".  Lint really is right to warn.
There really should not be any special exception for char*, even if the
source pointer was char**.  The exception is likely there because there
is too much code in production that uses too much of this kind of
trickery.

In this case it's the kind of structure an assembly language programmer
might dream up as being the most efficient.  However since we can
determine that the code is careful to manage and keep separate the
different areas of the storage, the warning can safely be turned off.
Here we only want "char"-sized access to the latter part of the object,
but the first part of the object is still only an array of char
pointers.  These are fundamentally incompatible data types and it's only
the low-level nature of C that even allows us to merge the two types of
data into the same object.

Fundamentally though there would be no significant loss of efficiency if
the data objects in this case were separated.  Indeed it may even be
possible to modify the algorithm in such a way that no additional copy
of the data is necessary, nor would an array of pointers into the data
be necessary, since the storage for the string being parsed is in fact
modifiable.  I.e. lint's warning really is acceptable and even desirable
and correct since the questionable code can easily be changed to
something that will not require either a warning or any other trickery.
I suspect the same rule of thumb applies to every other situation where
lint may generate such a warning too (though other situations may be in
sections of code where performance is more critical, thus it is
sometimes reasonable to turn off the warning).

-- 
                                                Greg A. Woods
                                                Planix, Inc.

<woods%planix.com@localhost>       +1 416 218-0099        http://www.planix.com/

Attachment: pgpgF3oD_dYOc.pgp
Description: PGP signature



Home | Main Index | Thread Index | Old Index