Current-Users archive

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

Re: Problems with packages on a netbsd-6 sparc



At Fri, 18 May 2012 07:55:35 +0100, David Laight <david%l8s.co.uk@localhost> 
wrote:
Subject: Re: Problems with packages on a netbsd-6 sparc
>
> On Thu, May 17, 2012 at 08:48:00PM -0700, Greg A. Woods wrote:
> > >       * Copy in passwd contents and make strings relative to space
> > >       * at the end of the buffer.
> > >       */
> > > +    memcpy(cp, pw, sizeof(struct passwd));
> > >      newpw = (struct passwd *) cp;
> > > -    memcpy(newpw, pw, sizeof(struct passwd));
> > >      cp += sizeof(struct passwd);
> > >      FIELD_COPY(pw, newpw, pw_name, nsize);
> > >      FIELD_COPY(pw, newpw, pw_passwd, psize);
> >
> > Why not avoid the non-intuitive memcpy() all together all the time and
> > just let the compiler do its job????
> >
> >     *newpw = *pw;
> >
> > C has allowed structure copies like this since at least C89, and much
> > earlier in many good compilers (the data pointed to by the fields which
> > are pointers still needs to be copied of course).
>
> You need to read the entire thread!
> C only allows you to take pointers to objects, cast them to certain other
> types (including char * and void *), cast them back to the SAME type
> and then dereference them.

I think that's kind of irrelevant given that I suggested getting rid of
the memcpy() entirely, but....

C allows pointers of, say, "void *" to be cast to _ANY_ type, alignment
restrictions aside.  Also, any function is allowed to return a "void *"
pointer which, given such a claim in that function's definition, the
programmer can then assume it will be aligned correctly for any use.
The standard malloc() function is such a function.

(So far as I can recall there is no requirement in C, and certainly not
old C or C89, that a "void *" pointer must be cast back to the type it
had before it was cast into a "void *" pointer.  Pointer aliasing like
that is not necessarily going to work in a _portable_ way if alignment
restrictions have not been dealt with somehow, but it's still allowed.)

If I'm not mistaken the "cp" pointer above, at the line where it is
assigned to "newpw" prior to the patch, is unchanged from the value it
had when it was most recently assigned from the return value of a
malloc() call.

In that case it MUST be properly aligned for any type.  Turning it into
a "struct passwd *" is perfectly valid -- the fact that the storage
being pointed at is larger than a "struct passwd" is irrelevant (it's
just an example of premature optimisation).

--
                                                Greg A. Woods
                                                Planix, Inc.

<woods%planix.com@localhost>       +1 250 762-7675        http://www.planix.com/

Attachment: pgpXb4QKKG2sQ.pgp
Description: PGP signature



Home | Main Index | Thread Index | Old Index