Topic: Must size_t be one of the existing types
Author: jss@lucid.com (Jerry Schwarz)
Date: Wed, 25 Mar 92 22:26:04 GMT Raw View
The C standard (as I read it) requires the types defined in stddef.h
(size_t, ptrdiff_t, wchar_t) to be one of the existing integral types.
Can anybody shed light on the reason for this. What, if anything,
would go wrong if these were distinct integral types.
My interest in this question comes from my work on the C++ standards
committee. Knowing when two types are distinct and when they are the
same tends to be more important in C++ than in C because of function
overloading in C++.
-- Jerry Schwarz
Author: jfw@ksr.com (John F. Woods)
Date: 26 Mar 92 12:52:33 EST Raw View
jss@lucid.com (Jerry Schwarz) writes:
>The C standard (as I read it) requires the types defined in stddef.h
>(size_t, ptrdiff_t, wchar_t) to be one of the existing integral types.
> Can anybody shed light on the reason for this. What, if anything,
> would go wrong if these were distinct integral types.
It sounds like you think they are all the *same* integral type, which is
false. Section 4.1.5 Common Definitions <stddef.h> only rquires that
ptrdiff_t be "the signed integral type of the result of subtracting two
pointers", size_t be "the unsigned integral type of the result of the
sizeof operator" (hence obviously a different type from ptrdiff_t), and
wchar_t "an integral type whose range of values can represent distinct codes
for all members of the largest extended character set specified among the
supported locales". They can certainly all be distinct, and there is not
even a guarantee that they are the same type as any of "char", "short", "int",
or "long". An implementation with 32 bit longs and 64 bit pointers which
allows single objects to span more than 4 gigabytes would need some extension
types sufficiently long to hold size_t and ptrdiff_t ("long long" or "__int64"
or whatever).
What would go wrong? Lots of code does
int s = sizeof(object);
which could fail badly; there is also
printf("%d\n", sizeof(object));
printf("%ld\n", sizeof(object));
printf("%ld\n", (long)sizeof(object));
*none* of which are guaranteed to be correct.
Author: chased@rbbb.Eng.Sun.COM (David Chase)
Date: 26 Mar 92 19:20:53 GMT Raw View
>jss@lucid.com (Jerry Schwarz) writes:
>>The C standard (as I read it) requires the types defined in stddef.h
>>(size_t, ptrdiff_t, wchar_t) to be one of the existing integral types.
>> Can anybody shed light on the reason for this. What, if anything,
>> would go wrong if these were distinct integral types.
In article <10961@ksr.com> jfw@ksr.com (John F. Woods) writes:
>It sounds like you think they are all the *same* integral type, which is
>false.
I think you missed the question. (At least, you missed the problem
that I saw). Is this (C++) skeleton legal?
#include <stddef.h>
void print(size_t) { ... };
void print(ptrdiff_t) { ... };
void print(wchar_t) { ... };
Without further knowledge of the contents of stddef.h, you cannot say.
Overloaded function names give you a nice sharp tool to juggle. Being
able to say that "these different names are distinct, we promise"
gives you a wee bit more control of what is happening. One way to do
this (bizarre as it seems at first) would be to use object
(non-integral) types. Another might be to introduce some technique
for "painting" integral types.
David Chase
Sun
Author: diamond@jit345.bad.jit.dec.com (Norman Diamond)
Date: Fri, 27 Mar 92 00:50:12 GMT Raw View
In article <1992Mar25.222604.25326@lucid.com> jss@lucid.com (Jerry Schwarz) writes:
>The C standard (as I read it) requires the types defined in stddef.h
>(size_t, ptrdiff_t, wchar_t) to be one of the existing integral types.
If, by "existing", you mean "standardized by ANSI chapter 3", then I
am not sure if this has been officially asked and/or ruled on or not.
However, regarding some other cases where the degree of standardization
is not explicitly clear, I have seen some posted assertions that would
tend to support your reading.
>Can anybody shed light on the reason for this.
Don't know. The committee's reasons might not have matched any of ours,
and they might not have even considered any reason for doing it this way
or otherwise. Indeed, since the matter was not explicitly addressed in
the standard, the latter possibility seems rather likely.
>What, if anything, would go wrong if these were distinct integral types.
The rules for arithmetic promotion would be unclear. What happens when
you add a long plus a ptrdiff_t? If ptrdiff_t has to be one of the types
standardized in chapter 3, then we know that the result will be a long.
Also, it inspires confidence in casting to (long) and printing with "%ld".
If these can be distinct types, then the same things can go wrong as the
currently contested issue of "long long" extensions.
>My interest in this question comes from my work on the C++ standards
>committee. Knowing when two types are distinct and when they are the
>same tends to be more important in C++ than in C because of function
>overloading in C++.
Yeah, I can see that. But considering that C++ has already disabled
backwards compatibility with C over precisely this issue with enums,
perhaps you shouldn't worry too much about doing the same to these other
types. If it benefits C++ to make them distinct, then do so.
[Personal opinion only.]
--
Norman Diamond diamond@jit081.enet.dec.com
If this were the company's opinion, I wouldn't be allowed to post it.
"Yeah -- bad wiring. That was probably it. Very bad."
Author: boehm@parc.xerox.com (Hans Boehm)
Date: 27 Mar 92 17:01:05 GMT Raw View
jss@lucid.com (Jerry Schwarz) writes:
>The C standard (as I read it) requires the types defined in stddef.h
>(size_t, ptrdiff_t, wchar_t) to be one of the existing integral types.
My reading of the standard agrees with yours (in spite of an earlier
posting that made a different assumption). It seems to me that this
point is important, even in C. If I have a C implementation on a 64
bit machine with sizeof(long) = 4, then sizeof(ptrdiff_t) <= sizeof(long)
implies that I am essentially restricted to a 2 GB address space.
Thus this can't look much like a 64 bit machine anymore.
(There are other reasons why that's mostly true anyway. Ftell is defined
to return a long, not a size_t.)
(The above argument technically implies only that an array is limited to
2 GB, since the standard doesn't allow me to subtract two arbitrary
pointers of the same type. But I have my doubts that an implementation
with 64 bit pointers and 32 bit pointer differences would be well received.)
Hans-J. Boehm
(boehm@parc.xerox.com)
Author: jfw@ksr.com (John F. Woods)
Date: 27 Mar 92 13:19:00 EST Raw View
(First, for the benefit of comp.std.c++ readers, I will point out that I didn't
understand the C++ motivation for the question, so you should just ignore my
previous blithering; I'm only posting this to comp.std.c++ so you can see
this apology, so you can hit 'n' now :-).
diamond@jit345.bad.jit.dec.com (Norman Diamond) writes:
>The rules for arithmetic promotion would be unclear. What happens when
>you add a long plus a ptrdiff_t? If ptrdiff_t has to be one of the types
>standardized in chapter 3, then we know that the result will be a long.
>Also, it inspires confidence in casting to (long) and printing with "%ld".
>If these can be distinct types, then the same things can go wrong as the
>currently contested issue of "long long" extensions.
Contrary to my original belief, apparently ptrdiff_t and size_t must be
one of the 4 basic integral types (signed and unsigned flavors, respectively,
of course). So says the Rationale, in 3.3.3.4, though I'll be darned if I
can see where in the Standard they derive the "implied" restriction. On the
other hand, the Rationale was written by people more knowledgable than I,
so I'm inclined to believe it. (Does anyone have concrete counterarguments?)
Author: steve@taumet.com (Steve Clamage)
Date: Sat, 28 Mar 1992 17:59:10 GMT Raw View
boehm@parc.xerox.com (Hans Boehm) writes:
>jss@lucid.com (Jerry Schwarz) writes:
>>The C standard (as I read it) requires the types defined in stddef.h
>>(size_t, ptrdiff_t, wchar_t) to be one of the existing integral types.
>It seems to me that this
>point is important, even in C. If I have a C implementation on a 64
>bit machine with sizeof(long) = 4, then sizeof(ptrdiff_t) <= sizeof(long)
>implies that I am essentially restricted to a 2 GB address space.
>Thus this can't look much like a 64 bit machine anymore.
This reply, like some others, does not address the question. Since I
am as interested as Jerry in the actual question, I'll take a stab
at a more detailed explanation.
As explained in earlier postings, C++ code could be made more portable
if the standard types above were (or could be made in C++) types
distinct from all other standard types. The issue is not to make a
27-bit size_t or 13-bit wchar_t, but just to make the types distinct.
For example, types int and long are distinct, even though they may have
the same implementation. Thus, the code
int *ip = ... ;
long *lp = ip;
is never legal (due to a type conflict), no matter how int and long are
implemented.
The question could then be stated this way: Suppose we make size_t,
wchar_t, and ptrdiff_t of a size suitable for the C/C++ implementation,
and futher suppose that each of these types is implemented in the same
way as one of the standard types. Is there anything wrong (in the sense
of breaking conforming C programs) with making these types distinct?
The C standard presently makes size_t implementation-defined. No C
program can rely on size_t being the same as unsigned int, for example,
since it need not be. Similarly, it can't rely on which promotion rules
will be used if a value of type size_t appears in an expression. It
seems to me that no portable assumptions are broken by making size_t a
distinct type, rather than a synonym for some existing type. (In C++.
We are not talking about an implementation calling itself Standard C
in this case. We would also have to say something about promotion
rules in expressions. Assume something sensible.)
Finally, we are also not worried about the name-space problem. A
simple implemention would have, for example, __size_t as a predefined
type name inside the compiler, and applicable standard headers would
just typedef size_t to be __size_t.
Does anyone see any problems with this?
--
Steve Clamage, TauMetric Corp, steve@taumet.com
Vice Chair, ANSI C++ Committee, X3J16
Author: clive@x.co.uk (Clive Feather)
Date: 31 Mar 92 15:07:43 GMT Raw View
In article <10985@ksr.com> jfw@ksr.com (John F. Woods) writes:
> Contrary to my original belief, apparently ptrdiff_t and size_t must be
> one of the 4 basic integral types (signed and unsigned flavors, respectively,
> of course). So says the Rationale, in 3.3.3.4, though I'll be darned if I
> can see where in the Standard they derive the "implied" restriction.
The term "integral type" is defined by the standard (ISO section 6.1.2.5):
| There are four _signed_integer_types_, designated as _signed_char_,
| _short_int_, _int_, and _long_int_.
| For each of the signed integer types, there is a corresponding (but
| different) _unsigned_integer_type_ [...].
| An _enumeration_ consists of a set of named integer constant values.
| Each distinct enumeration consitutes a different _enumeration_type_.
| The type _char_, the signed and unsigned integer types, and the
| enumerated types are collectively called _integral_types_.
And in ISO section 3:
| Other terms are defined at their first appearance, indicated by
| _italic_ type.
--
Clive D.W. Feather | IXI Limited | If you lie to the compiler,
clive@x.co.uk | 62-74 Burleigh St. | it will get its revenge.
Phone: +44 223 462 131 | Cambridge CB1 1OJ | - Henry Spencer
(USA: 1 800 XDESK 57) | United Kingdom |