correct code for pointer subtraction
Tapani Tarvainen
tarvaine at tukki.jyu.fi
Fri Jan 6 06:28:36 AEST 1989
In article <PINKAS.89Jan3082456 at hobbit.intel.com> pinkas at hobbit.intel.com (Israel Pinkas ~) writes:
>> > > static int a[30000];
>> > > printf("%d\n",&a[30000]-a);
> Let's ignore the fact that
>there is no a[30000] (and that taking its address is invalid).
I have been told that dpANS explicitly states that the address of
"one-after-last" element of an array may be taken, and subtractions
like the above are legal and should give correct result.
I do not have an access to the the dpANS - could somebody who does
please look this up?
In any case all compilers I know of do it just fine
(unless some kind of overflow occurs, like in this very example -
but that's independent of how big the array is declared)
and a lot of existing code does rely on it.
Regarding the original problem, it *is* possible to do the subtraction
correctly, although not simply by using unsigned division.
Here is one way I think would work (on the left is what Turbo C
generates, for comparison):
xor dx,dx
mov ax,&a[30000] mov ax,&a[30000]
sub ax,a sub ax,a
mov bx,2 mov bx,2
cwd sbb dx,dx
idiv bx idiv bx
I.e., take advantage of the fact that we can treat carry and
AX as one 17-bit register containing the result of subtraction.
It will cost a few clock cycles, I'm afraid.
In this particular case it can actually be done with
no speed penalty with the following trick:
mov ax,&a[30000]
sub ax,a
rcr ax
In general case it seems we must choose between doing it fast
and getting it right every time. Perhaps a compiler option for
those who would otherwise use an old compiler version to save
the two cycles or whatever it costs...
Tapani Tarvainen
------------------------------------------------------------------
Internet: tarvainen at jylk.jyu.fi -- OR -- tarvaine at tukki.jyu.fi
BitNet: tarvainen at finjyu
More information about the Comp.lang.c
mailing list