svn commit: r212064 - head/sys/boot/pc98/boot2

Kostik Belousov kostikbel at gmail.com
Tue Aug 31 20:34:03 UTC 2010


On Tue, Aug 31, 2010 at 10:11:15PM +0200, Dimitry Andric wrote:
> On 2010-08-31 21:51, Kostik Belousov wrote:
> > What is the undefined behaviour you are claiming there ?
> 
> Arithmetic on a NULL pointer, which is undefined.  The C standard says
> in 6.5.6 (additive operators):
> 
> 3. For subtraction, one of the following shall hold:
>    ? both operands have arithmetic type;
>    ? both operands are pointers to qualified or unqualified versions of
>      compatible object types; or
>    ? the left operand is a pointer to an object type and the right
>      operand has integer type. (Decrementing is equivalent to
>      subtracting 1.)
> 
> But NULL does not point to any specific object.  A few paragraphs down
> it says:
> 
> 9. When two pointers are subtracted, both shall point to elements of
>    the same array object, or one past the last element of the array
>    object; the result is the difference of the subscripts of the two
>    array elements.
> 
> NULL does not point to anything, so you cannot subtract NULL from a
> pointer, nor subtract a pointer from NULL (as is done here).
Going into this mode, can you cite the spell that makes the NULL to
not point to anything ? There is 6.3.2.3,
----------------------------------------------------
If a null pointer constant is converted to a pointer type, the resulting
pointer, called a null pointer, is guaranteed to compare unequal to a
pointer to any object or function.
----------------------------------------------------
In other words, any object instantiated by C source code (be it
declaration, malloc-kind allocation etc) cannot have address equial
to NULL. But this does not make NULL lesser pointer then any other.

> 
> Apparently gcc allows it, possibly as an extension?  But clang does not,
> and will generate a 'unreachable' instruction for this expression.  (I
> encountered this when I was trying to get boot2 compiled by clang small
> enough to fit in 7168 bytes.)
> 

6.5.6.9 is worded to allow tagged architectures to support ANSI C.
Clang behaviour is literalism and very unuseful for freestanding
environments on the usual architectures, where whole address
space is a single char array.

I do not see the substraction of two pointers in the changed fragment of code.
:#define  PTOV(pa)        ((caddr_t)(pa) - __base)
caddr_t is indeed char *, but __base is u_int32_t.
And there seems to be no substraction of pointers in the old version of
-    return *(p + 0x401) * 128 * 1024 + *(u_int16_t *)(p + 0x594) * 1024 * 1024;
+    return *p * 128 * 1024 + *(u_int16_t *)(p + (0x594 - 0x401)) * 1024 * 1024;

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 196 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/svn-src-head/attachments/20100831/248782c0/attachment.pgp


More information about the svn-src-head mailing list