Re: C89, size_t, and long
- From: Yevgen Muntyan <muntyan.removethis@xxxxxxxx>
- Date: Wed, 14 Mar 2007 19:14:36 GMT
Eric Sosman wrote:
Yevgen Muntyan wrote On 03/14/07 14:26,:Hey,
I was reading C99 Rationale, and it has the following two QUIET CHANGE
paragraphs:
6.5.3.4: "With the introduction of the long long and extended integer
types, the sizeof operator may yield a value that exceeds the range
of an unsigned long."
6.5.6: "With the introduction of the long long and extended integer
types, the subtraction of pointers may return a value that exceeds the
range of a long."
Was it required by C89 that result of sizeof() fits into unsigned long,
and that pointer subtraction result fits into long?
"Yes" and "Almost," respectively. C89 offered a fixed
set of integer types, of which {,un}signed long was the widest.
The implementation was free to provide additional types that
behaved like integers, but they were not "integer types" as
C89 defined them. C89 also required that size_t and ptrdiff_t
be aliases for "integer types," so they could not be wider than
long. If an implementation offered wider types, they were not
"integer types" and hence were not candidates for size_t and
ptrdiff_t.
On machines whose longs are the same width as their pointers
(more generally, no wider than their pointers), this means that
ptrdiff_t cannot be wide enough to express the result of all
pointer subtractions. An easy example:
char *p = malloc(LONG_MAX + 2u); /* assume success */
char *q = p + LONG_MAX + 2u;
ptrdiff_t delta = q - p;
We will now have p < q but (probably) delta < 0.
If yes, then MS
Win64 implementation is not C89-conforming (while sizeof case may be
arguable, I guess, we certainly can ask to malloc more than ULONG_MAX
bytes, and get pointer arithmetics which needs more than (unsigned)
long). If no, why these two paragraphs, if programs which relied on long
being big enough were already broken?
I don't know MS' Win64 implementation well enough to comment
on whether it's broken or not.
It has 32-bit long, same as int, and naturally 64-bit size_t.
As for programs that assumed
size_t and ptrdiff_t were no wider than long, no: They were not
broken under C89's rules, because C89 implied the truth of the
assumption.
Then these programs may be broken on Win64, right? Say, this code:
void do_something (void *buf, unsigned long len)
{
memset (buf, 1, len);
}
int main (void)
{
size_t i;
size_t size = BIG_NUMBER;
char *p = malloc (size);
if (p)
{
do_something (p, size);
assert (p[size-1]);
}
return 0;
}
BIG_NUMBER can be defined as some square root of SIZE_MAX+1 multiplied
by two or something, so we don't need to invent functions which get
us a big buffer. I guess MS estimated somehow how much of their code
uses long as 32-bit int, and decided it's more than code which uses
unsigned long as size_t. Anyway, is MS Win64 implementation not
C89-conforming (it's an important thing, isn't it)? Or I do miss
something?
Thanks,
Yevgen
.
- Follow-Ups:
- Re: C89, size_t, and long
- From: Keith Thompson
- Re: C89, size_t, and long
- From: Eric Sosman
- Re: C89, size_t, and long
- References:
- C89, size_t, and long
- From: Yevgen Muntyan
- Re: C89, size_t, and long
- From: Eric Sosman
- C89, size_t, and long
- Prev by Date: Re: Real Life Unions
- Next by Date: Re: incrementing void *
- Previous by thread: Re: C89, size_t, and long
- Next by thread: Re: C89, size_t, and long
- Index(es):
Relevant Pages
|