I'm writing portable code where I have to deal with "length" and
"index" values, which are all required to be unsigned long (32-bit
unsigned integer) by an industry standard.
I also have to use a "portable" third-party c++ package that uses
"size_t" instead of unsigned long for index and length values;
on one of our platforms, "size_t" is defined as "unsigned int"
(32-bit), on another platform "size_t" is defined as "unsigned long"
(32-bit). so we're getting compiler-warnings about implicitly casting
unsigned-long to unsigned-int on one platform.
i would like to write something using asserts so that we insure that
we don't drop bits on the cast:
void myFunc ( unsigned long len, unsigned long index )
{
assert ( len <= SIZE_T_MAX ); // to catch porting problems...
assert ( index <= SIZE_T_MAX );
thirdPartyFunc ( (size_t) len, (size_t) index );
}
Is the maximum value for a value of type size_t supposed to be
equal to UINT_MAX or some other ANSI constant?
Late idea -- can we say: "assert( sizeof(long) == sizeof(size_t));" ?
Yes, it is equal with some constant from limits.h, but the standard
doesn't specify with which one :-)
Since size_t is guaranteed to be an unsigned integer type, you can
define your own SIZE_T_MAX without too many problems:
#define SIZE_T_MAX ((size_t)(~0UL))
>
>Late idea -- can we say: "assert( sizeof(long) == sizeof(size_t));" ?
If you want your code to be aborted on any platform where
sizeof(size_t) < sizeof(long), you can use that assert, but do you want
to do that?
Dan
--
Dan Pop
CERN, CN Division
Email: dan...@cernapo.cern.ch
Mail: CERN - PPE, Bat. 31 R-004, CH-1211 Geneve 23, Switzerland
>Is there some kind of definition to tell me what the maximum value
>of type size_t is supposed to be?
>I'm writing portable code where I have to deal with "length" and
>"index" values, which are all required to be unsigned long (32-bit
>unsigned integer) by an industry standard.
Are they required to be unsigned long or 32-bit unsigned integer? This
is not the same. On Alphas, for example, long is 64 bits.
>I also have to use a "portable" third-party c++ package that uses
>"size_t" instead of unsigned long for index and length values;
>on one of our platforms, "size_t" is defined as "unsigned int"
>(32-bit), on another platform "size_t" is defined as "unsigned long"
>(32-bit). so we're getting compiler-warnings about implicitly casting
>unsigned-long to unsigned-int on one platform.
>i would like to write something using asserts so that we insure that
>we don't drop bits on the cast:
If those index and size values refer to objects in memory (not in
files), size_t seems to be the appropriate type, since it must be large
enough to represent the size of any object. Even if long is larger than
size_t, all the values your variables will hold are small enough to fit
in a size_t, so you won't lose information in the cast.
If you are referring to disk structures, however, size_t is the wrong
type, and you need some way to read and write long values from and to
disk, also.
>void myFunc ( unsigned long len, unsigned long index )
>{
> assert ( len <= SIZE_T_MAX ); // to catch porting problems...
> assert ( index <= SIZE_T_MAX );
> thirdPartyFunc ( (size_t) len, (size_t) index );
>}
>Is the maximum value for a value of type size_t supposed to be
>equal to UINT_MAX or some other ANSI constant?
Yes, but you don't know which. ((size_t)-1) or ((size_t)~0) are
portable expressions for SIZE_T_MAX.
>Late idea -- can we say: "assert( sizeof(long) == sizeof(size_t));" ?
Yes, if you want to get early warning, that there might be a problem.
The indiviual asserts above only get you when there really is one.
hp
--
_ | h...@vmars.tuwien.ac.at | Peter Holzer | TU Vienna | CS/Real-Time Systems
|_|_) |------------------------------------------------------------------------
| | | It's not what we don't know that gets us into trouble, it's
__/ | what we know that ain't so. -- Will Rogers
Try
assert(len == (size_t)len);
assert(index == (size_t)index);
which tests exactly for the required condition.
(Note that this only works because size_t is unsigned; otherwise the cast
can cause undefined behavior.)
>Late idea -- can we say: "assert( sizeof(long) == sizeof(size_t));" ?
Yes, you can do that.
--
<J Q B>
>In <keithr-08...@keithr.khis.com> kei...@khis.com (c. keith ray) writes:
>>Is the maximum value for a value of type size_t supposed to be
>>equal to UINT_MAX or some other ANSI constant?
>
>Yes, it is equal with some constant from limits.h, but the standard
>doesn't specify with which one :-)
>
>Since size_t is guaranteed to be an unsigned integer type, you can
>define your own SIZE_T_MAX without too many problems:
>
>#define SIZE_T_MAX ((size_t)(~0UL))
Ahem, what if
typedef unsigned int size_t;
and
sizeof(long) > sizeof(int)
?
:-)
--
Kevlin Henney
repeat 3 echo there\'s no place like ~
It would work even if size_t were signed. If an integral value is demoted
to a shorter signed type and the value doesn't fit, then the result is
implementation-defined, and the result would have to be less than the
positive value that didn't fit.
--
<< If this were the company's opinion, I would not be allowed to post it. >>
A program in conformance will not tend to stay in conformance, because even if
it doesn't change, the standard will. Force = program size * destruction.
Every technical corrigendum is met by an equally troublesome new defect report.
Then it works. The value ULONG_MAX is reduced modulo the value 1 greater
than UINT_MAX and the result is UINT_MAX.
>In article <771253...@wslint.demon.co.uk> Kev...@wslint.demon.co.uk writes:
>>In article <1994Jun9.1...@dxcern.cern.ch>
>> dan...@cernapo.cern.ch "Dan Pop" writes:
>>>Since size_t is guaranteed to be an unsigned integer type, you can
>>>define your own SIZE_T_MAX without too many problems:
>>>#define SIZE_T_MAX ((size_t)(~0UL))
>
>>Ahem, what if
>> typedef unsigned int size_t;
>>and
>> sizeof(long) > sizeof(int)
>
>Then it works. The value ULONG_MAX is reduced modulo the value 1 greater
>than UINT_MAX and the result is UINT_MAX.
This is overcautiousness on my part for poor implementations that define
size_t as signed - which is *very* wrong. In such situations I guess it
would be better to stick to the standard and hack the header files.
>Yes, but you don't know which. ((size_t)-1) or ((size_t)~0) are
>portable expressions for SIZE_T_MAX.
Which is (as I argued before myself and was pointed out to me again by
Jutta in private email) not correct.
((size_t)-1) is a portable expression of SIZE_T_MAX, but ((size_t)~0)
will equal ((size_t)-0) (== 0) on ones-complement architectures.
((size_t)~0UL) (as somebody else proposed) is correct, though.