"Numerical Recipes in C" is nonport
mcdonald at uxe.cso.uiuc.edu
mcdonald at uxe.cso.uiuc.edu
Tue Aug 30 00:07:00 AEST 1988
>As I understand the draft standard, you may portably compute address
>of the location *after* the last element of the array, but not the
>location *before* the first element of the array.
>Here is at least one architecture that breaks 80X86.
> char *foo = malloc(65635)
> /* foo <- address 4a33:0000 */
> char *bar = foo-1;
>Ok, now what is the value of "(4a33:0000)-1"? Answer: there isn't
>one. The draft standard doesn't say that nonconforming programs will
>break on all machines, just that they won't work on all machines.
Interesting. The dovumentation says that the argument of malloc
is an unsigned int, for which the maximum value is 65535. Heaven knows
what would happen if you actually tried this. But let's say we go to
huge model and use halloc(65635,1) which is legal but obviously
nonportable. OR you could say
char foo[65635];
and compile in the huge model. In either case you get something like
2000:0000 for bar = foo;
and 1000:FFFF for bar = foo; bar--;
and if you do bar = foo; bar--; bar++; you get back 2000:0000.
Thus on the 8086 in huge model it indeed works (but, we all agree,
is nonportable).
Actually if you write
char foo[65536];
in large model it works: the pointer arithmetic works on only the
offset portion of the address, so you get wraparounds, but as
long as you don't try to dereference the resulting pointers everything
works. If you DO try to dereference bar = foo; bar--; you of
course actually access foo[65535].
In small data model, the first few bytes of the data segment
are reserved for the word "Microsoft" so the worst you can do
there is mess with their name. The last bytes of the segment are the
stack, so if you DO dereference past the end of the legal data
area, disaster most certainly COULD occur.
The fact that it may work doesn't mean that it is pretty, though.
Doug McDonald
P.S. This is is for Microsoft C
.
More information about the Comp.lang.c
mailing list