Date: Tue, 14 Feb 2006 12:04:02 +1100 (EST) From: Bruce Evans <bde@zeta.org.au> To: "M. Warner Losh" <imp@bsdimp.com> Cc: keramida@ceid.upatras.gr, arch@FreeBSD.org, stefanf@FreeBSD.org, cperciva@FreeBSD.org, des@des.no Subject: Re: [releng_6 tinderbox] failure on sparc64/sparc64 Message-ID: <20060214083530.K22079@epsplex.bde.org> In-Reply-To: <20060213.094336.118368793.imp@bsdimp.com> References: <20060213.002310.125802352.imp@bsdimp.com> <20060213082129.GA13997@flame.pc> <43F04494.4030900@freebsd.org> <20060213.094336.118368793.imp@bsdimp.com>
next in thread | previous in thread | raw e-mail | index | archive | help
[Someone wrote that certain accesses except via unsigned char are undefined.] On Mon, 13 Feb 2006, M. Warner Losh wrote: > In message: <43F04494.4030900@freebsd.org> > Colin Percival <cperciva@freebsd.org> writes: > : Giorgos Keramidas wrote: > : > On 2006-02-13 00:23, "M. Warner Losh" <imp@bsdimp.com> wrote: > : >> struct foo foo; > : >> uint32_t value[sizeof(foo) / sizeof(uint32_t)]; > : >> > : >> memcpy(value, &foo); > : >> // write out value one 32-bit word at a time > : >> > : >> Is that right? Or at least 'proper' here means defined. > : > > : > AFAIK, yes. > : > : I agree that the behaviour of the above code is defined, but > : I'd be much happier if value[] was defined to be an array of > : length ((sizeof(foo) - 1) / sizeof(uint32_t) + 1), just in > : case sizeof(foo) happens to not be a multiple of 4. :-) The behaviour of the above code is highly undefined. There is no `size' arg in the call to memcpy(), and fixing this alone leaves various bugs and a complicated analysis to show that the behaviour is not completely undefined. The C standard only explicitly defines copying from an object _to_ an array of unsigned char. That copying back doesn't give undefined behaviour is only implicitly defined. The above is much further from being explictly defined since it copies essentially random bits _from_ a nameless intermediate array of unsigned char to another object. The behaviour would certainly be undefined for most types of final object since there may be trap bits in the final object, or it might just be implementation defined and not what is wanted because there are non-trap padding bits in the final object. However, uint32_t doesn't have any padding bits, so it may be possible to show that the behaviour of accessing the final object is defined (and useful). I think this is equivalent to showing that the behaviour of the following is defined: auto uint32_t value; value = 0; /* undefined without this? */ memset(&value, random(), 1); value++; > It won't matter given how I'm going to fix this problem... Why not just access the object as an array of unsigned chars as someone wrote? Write it out 1 unsigned char at a time for the simple version. This avoids the complications. Bruce
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20060214083530.K22079>