When is a cast not a cast?

Chris Torek chris at mimsy.UUCP
Sat May 20 15:30:57 AEST 1989


>>In article <2890 at buengc.BU.EDU> bph at buengc.BU.EDU (Blair P. Houghton)
presented an
>[argument for allowing pointer addition so we can hand-optimize a loop]
(his paraphrase).

>In article <17569 at mimsy.UUCP> I commented:
>>I cannot think of a realistic example of this.

In article <2906 at buengc.BU.EDU> bph at buengc.BU.EDU (Blair P. Houghton) writes:
>And I don't know why we need arrays at all...or Pascal, for that matter.
>:-) :-) :-) :-) :-) :-) :-) :-) :-) :-) :-) :-) :-) :-) :-) :-) :-) :-)

Actually, I was wishing you had provided one so I could shoot it down. :-)
(No fair making up straw men....)

Back to me:
>>Anyway, consider another argument against pointer+pointer addition:
>>Suppose we have a segmented architecture, ....

>You're using an architecture to specify C.  Is that not a no-no?

It might be, but that is not what I did.  A better analogy is found
in mathematics:  To prove a statement, you must show that it is
always true.  To disprove it, a single counterexample suffices.

[much deleted]

>Further, the examples you give are not limited to pointer+pointer
>arithmetic.  They'd result in over/underflow even if done in
>proper pointer+int form.

Not so.  (My `examples' were only to describe the behaviour of
a hypothetical architecture; I did not provide an example of pointer
addition.)  In any case, if you will consider for a bit you can
come up values for the following:

	pointer_type p, q, r;
	integral_type pqdiff;

	r = (p + q) / 2;	/* p+q overflows */
	r = p + (q - p) / 2;	/* no subexpression overflows */

>The same would be true if we were trying to add unsigned integers
>that weren't pointers at all.

No; unsigned arithemetic is modular arithmetic.  (It is also quite
slow on some architectures.)

>Or a couple of really big floats...

It is true that in

	double a, b, avg;
	...
	avg = (a + b) / 2.0;

the computation of (a+b) might overflow.  To avoid this, a careful
programmer will use

	avg = a + (b - a) / 2.0;

where it matters.  The key difference between this and the pointer
version is that one can portably write

	#define SAFE 10000.0	/* see pANS for a larger safe value */
	if (a < SAFE && b < SAFE)
		avg = (a + b) / 2.0;
	else
		avg = a + (b - a) / 2.0;

whereas there is no way to portably write

	if (p < ??? && q < ???) /* cannot fill in ??? portably */
		avg_of_p_and_q = (p + q) / 2;
	else
		avg_of_p_and_q = p + (q - p) / 2;

(as I mentioned in an article just posted moments ago).
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris at mimsy.umd.edu	Path:	uunet!mimsy!chris



More information about the Comp.lang.c mailing list