469,317 Members | 1,759 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,317 developers. It's quick & easy.

Assuming size_t is unsigned long

Hello,

Is it safe to assume a size_t is an unsigned long? (is it forced by
the standard?)

Thank you,

Paulo Matos

Apr 9 '07 #1
24 9736
Paulo Matos said:
Hello,

Is it safe to assume a size_t is an unsigned long?
Only if it is an unsigned long, which it may well not be.
(is it forced by the standard?)
No, the Standard only requires that size_t be an unsigned integer type
(unsigned char, unsigned short, unsigned int, unsigned long, unsigned
long long if you have it) that can represent the size of any object. It
is not even required to be a standard unsigned integer type. It might,
for example, be defined like this:

typedef unsigned __internal_27_bit_integer_type size_t;

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Apr 9 '07 #2
Richard Heathfield wrote:
Paulo Matos said:

>>Hello,

Is it safe to assume a size_t is an unsigned long?


Only if it is an unsigned long, which it may well not be.

>>(is it forced by the standard?)


No, the Standard only requires that size_t be an unsigned integer type
(unsigned char, unsigned short, unsigned int, unsigned long, unsigned
long long if you have it) that can represent the size of any object. It
is not even required to be a standard unsigned integer type. It might,
for example, be defined like this:

typedef unsigned __internal_27_bit_integer_type size_t;
From C99 6.5.3.4 #20 :
"This requirement implicitly restricts size_t to be a synonym for an
existing unsigned integer type".

That rules out __internal_27_bit_integer_type, doesn't it?

Bjrn

--
Looking for an embeddable web server?
http://www.metasystems.no/products/h...der/index.html
Apr 9 '07 #3
B. Augestad said:
Richard Heathfield wrote:
>[sizeof] might, for example, be defined like this:

typedef unsigned __internal_27_bit_integer_type size_t;

From C99 6.5.3.4 #20 :
"This requirement implicitly restricts size_t to be a synonym for an
existing unsigned integer type".

That rules out __internal_27_bit_integer_type, doesn't it?
I'm looking at C99, and 6.5.3.4 only goes up to para 7.

I checked n1124.pdf instead, and that goes up to 7 too.

And a search for "implicitly restricts size_t" fails to produce any
matches in either document.

So I don't know what you're talking about.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Apr 9 '07 #4
B. Augestad wrote:
Richard Heathfield wrote:
>Paulo Matos said:

>>Hello,

Is it safe to assume a size_t is an unsigned long?


Only if it is an unsigned long, which it may well not be.

>>(is it forced by the standard?)


No, the Standard only requires that size_t be an unsigned integer type
(unsigned char, unsigned short, unsigned int, unsigned long, unsigned
long long if you have it) that can represent the size of any object.
It is not even required to be a standard unsigned integer type. It
might, for example, be defined like this:

typedef unsigned __internal_27_bit_integer_type size_t;

From C99 6.5.3.4 #20 :
"This requirement implicitly restricts size_t to be a synonym for an
existing unsigned integer type".
Where did you find this? ISO/IEC 9899:1999 (E) has a
section 6.3.5.4 (concerning the sizeof operator), but that
section has only seven paragraphs, not twenty-plus. Also,
Acrobat is unable to find the phrase "implicitly restricts"
anywhere in the document.
That rules out __internal_27_bit_integer_type, doesn't it?
Even if the passage is present and I've merely failed to
find it, I think __internal_27_bit_integer_type is allowed
anyhow. That type might also be known under other aliases
like uint27_t or uint_least25_t, which are (if they exist)
"integer types."

--
Eric Sosman
es*****@acm-dot-org.invalid
Apr 9 '07 #5
Richard Heathfield wrote:
B. Augestad said:

>>Richard Heathfield wrote:
>>>[sizeof] might, for example, be defined like this:

typedef unsigned __internal_27_bit_integer_type size_t;

From C99 6.5.3.4 #20 :
"This requirement implicitly restricts size_t to be a synonym for an
existing unsigned integer type".

That rules out __internal_27_bit_integer_type, doesn't it?


I'm looking at C99, and 6.5.3.4 only goes up to para 7.

I checked n1124.pdf instead, and that goes up to 7 too.

And a search for "implicitly restricts size_t" fails to produce any
matches in either document.

So I don't know what you're talking about.
I can see why, as I cannot find it myself right now. You see, I bought
the book version of the standard. The one bad thing about books is that
they aren't searchable. 6.5.3.4 was obviously way off, give me some time
to figure out what went wrong and browse through the book.

Bjrn.

--
Looking for an embeddable web server?
http://www.metasystems.no/products/h...der/index.html
Apr 9 '07 #6
B. Augestad wrote:
Richard Heathfield wrote:
>B. Augestad said:

>>Richard Heathfield wrote:

[sizeof] might, for example, be defined like this:

typedef unsigned __internal_27_bit_integer_type size_t;
From C99 6.5.3.4 #20 :
"This requirement implicitly restricts size_t to be a synonym for an
existing unsigned integer type".

That rules out __internal_27_bit_integer_type, doesn't it?

I'm looking at C99, and 6.5.3.4 only goes up to para 7.

I checked n1124.pdf instead, and that goes up to 7 too.

And a search for "implicitly restricts size_t" fails to produce any
matches in either document.

So I don't know what you're talking about.
I can see why, as I cannot find it myself right now. You see, I bought
the book version of the standard. The one bad thing about books is that
they aren't searchable. 6.5.3.4 was obviously way off, give me some time
to figure out what went wrong and browse through the book.

Bjrn.
Found it!

I really scared myself for a while there, unable to locate the quote and
quietly wondering if I finally had gone insane. :-)

The sentence is in 6.5.3.4, but not in the standard. The book version
consists of two parts, the C rationale and the C standard. I looked at
the wrong part, the rationale.

Sorry for the confusion this may have caused.
Bjrn

--
Looking for an embeddable web server?
http://www.metasystems.no/products/h...der/index.html
Apr 9 '07 #7
Eric Sosman wrote:
B. Augestad wrote:
>Richard Heathfield wrote:
>>Paulo Matos said:
Hello,

Is it safe to assume a size_t is an unsigned long?

Only if it is an unsigned long, which it may well not be.
(is it forced by the standard?)

No, the Standard only requires that size_t be an unsigned integer
type (unsigned char, unsigned short, unsigned int, unsigned long,
unsigned long long if you have it) that can represent the size of any
object. It is not even required to be a standard unsigned integer
type. It might, for example, be defined like this:

typedef unsigned __internal_27_bit_integer_type size_t;

From C99 6.5.3.4 #20 :
"This requirement implicitly restricts size_t to be a synonym for an
existing unsigned integer type".


Where did you find this? ISO/IEC 9899:1999 (E) has a
section 6.3.5.4 (concerning the sizeof operator), but that
section has only seven paragraphs, not twenty-plus. Also,
Acrobat is unable to find the phrase "implicitly restricts"
anywhere in the document.
Please see elsethread for an explanation of where I found it.
>
>That rules out __internal_27_bit_integer_type, doesn't it?


Even if the passage is present and I've merely failed to
find it, I think __internal_27_bit_integer_type is allowed
anyhow. That type might also be known under other aliases
like uint27_t or uint_least25_t, which are (if they exist)
"integer types."
So "existing" may mean existing in an implementation and not necessarily
existing in the C standard? Makes sense, I guess.

Bjrn


--
Looking for an embeddable web server?
http://www.metasystems.no/products/h...der/index.html
Apr 9 '07 #8
On Apr 9, 12:35 pm, Richard Heathfield <r...@see.sig.invalidwrote:
Paulo Matos said:
Hello,
Is it safe to assume a size_t is an unsigned long?

Only if it is an unsigned long, which it may well not be.
(is it forced by the standard?)

No, the Standard only requires that size_t be an unsigned integer type
(unsigned char, unsigned short, unsigned int, unsigned long, unsigned
long long if you have it) that can represent the size of any object. It
is not even required to be a standard unsigned integer type. It might,
for example, be defined like this:

typedef unsigned __internal_27_bit_integer_type size_t;
Well, I don't think there's a specific printf formatter for size_t,
right? So, how would you go about printing a size_t?
C FAQ says to use unsigned long... that's why I asked about size_t ==
unsigned long. That might be flawed since I may use %lu and size_t be
unsigned long long in the compiler. So, is there any portable way of
printing size_t?

Cheers,

Paulo Matos
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999http://www.cpax.org.uk
email: rjh at the above domain, - www.

Apr 9 '07 #9
Paulo Matos wrote:
Well, I don't think there's a specific printf formatter for size_t,
right? So, how would you go about printing a size_t?
In C99, there is. You can use "%zu".
C FAQ says to use unsigned long... that's why I asked about size_t ==
unsigned long. That might be flawed since I may use %lu and size_t be
unsigned long long in the compiler. So, is there any portable way of
printing size_t?
C90 disallows a size_t greater than unsigned long. So, you can use
this:

size_t s;
/* ... */
#if __STDC_VERSION >= 199901L
printf("%zu", s);
#else
printf("%lu", (unsigned long) s);
#endif

It's probably best put in a helper function, rather than copying the
check everywhere.

(This will not work for implementations that use C99 syntax with a C90
library. Such implementations do not conform to any standard, but are
used in the real world. Decide for yourself whether you want to
support them.)

Apr 9 '07 #10
B. Augestad wrote On 04/09/07 08:46,:
Eric Sosman wrote:
>>B. Augestad wrote:

>>>Richard Heathfield wrote:
Paulo Matos said:

>Hello,
>
>Is it safe to assume a size_t is an unsigned long?

Only if it is an unsigned long, which it may well not be.

>(is it forced by the standard?)

No, the Standard only requires that size_t be an unsigned integer
type (unsigned char, unsigned short, unsigned int, unsigned long,
unsigned long long if you have it) that can represent the size of any
object. It is not even required to be a standard unsigned integer
type. It might, for example, be defined like this:

typedef unsigned __internal_27_bit_integer_type size_t;
From C99 6.5.3.4 #20 :
"This requirement implicitly restricts size_t to be a synonym for an
existing unsigned integer type".


Where did you find this? ISO/IEC 9899:1999 (E) has a
section 6.3.5.4 (concerning the sizeof operator), but that
section has only seven paragraphs, not twenty-plus. Also,
Acrobat is unable to find the phrase "implicitly restricts"
anywhere in the document.

Please see elsethread for an explanation of where I found it.

>>>That rules out __internal_27_bit_integer_type, doesn't it?


Even if the passage is present and I've merely failed to
find it, I think __internal_27_bit_integer_type is allowed
anyhow. That type might also be known under other aliases
like uint27_t or uint_least25_t, which are (if they exist)
"integer types."

So "existing" may mean existing in an implementation and not necessarily
existing in the C standard? Makes sense, I guess.
That was one of the significant but largely unheralded
changes between C90 and C99. In C90, the "integer types"
were the basic nine: signed and unsigned char, short, int,
and long, plus plain char. C90 implementations were allowed
to provide additional exotic integer flavors, but any such
were not considered "integer types." Hence, the requirement
that size_t be an unsigned integer type meant that it could
not be one of the implementation's exotic additions.

C99 not only added the two long long variants to the
original suite of nine basic types, but also adopted language
(all that stuff about "rank") to allow exotic types to be
elevated to the status of "integer type." In effect, the
set of "integer types" became extensible, with rules in
place to govern the acceptable extensions. Types like size_t
are still described as "integer types," but the definition
now covers the exotic additions as well as the basic eleven.

Recently -- I think it was a week ago Sunday -- I read
that C0x plans to expand the integers further still. In
support of defensive programming, each of the eleven existing
types will gain a new "defensive" variant: "defensive signed
char," for example. The existing C90 types (retained for
backwards compatibility) will be known as "offensive." This
gives the programmer enough types to field a complete squad,
with the possibility of implementation-defined "special teams"
types in addition (subject to salary cap). The whole notion
is obviously rooted in American football and thus USA-centric,
but since all the internationalization stuff is already slated
for deletion this should surprise no one.

(Was it actually a week ago Sunday that I saw this? Yes,
I think it probably was ...)

--
Er*********@sun.com
Apr 9 '07 #11
On Apr 9, 3:19 pm, "Harald van Dijk" <true...@gmail.comwrote:
Paulo Matos wrote:
Well, I don't think there's a specific printf formatter for size_t,
right? So, how would you go about printing a size_t?

In C99, there is. You can use "%zu".
C FAQ says to use unsigned long... that's why I asked about size_t ==
unsigned long. That might be flawed since I may use %lu and size_t be
unsigned long long in the compiler. So, is there any portable way of
printing size_t?

C90 disallows a size_t greater than unsigned long. So, you can use
this:

size_t s;
/* ... */
#if __STDC_VERSION >= 199901L
printf("%zu", s);
#else
printf("%lu", (unsigned long) s);
#endif

It's probably best put in a helper function, rather than copying the
check everywhere.

(This will not work for implementations that use C99 syntax with a C90
library. Such implementations do not conform to any standard, but are
used in the real world. Decide for yourself whether you want to
support them.)

Didn't know about zu. Those are great news. Since I'm using std=c99 to
gcc I think I'll stick with zu. Thank you!

Apr 9 '07 #12
Paulo Matos wrote:
Well, I don't think there's a specific printf formatter for size_t,
right?
Yes, there is: "%zu"
So, how would you go about printing a size_t?
With "%zu"
C FAQ says to use unsigned long... that's why I asked about size_t ==
unsigned long. That might be flawed since I may use %lu and size_t be
unsigned long long in the compiler. So, is there any portable way of
printing size_t?
If you don't have "%zu" available, use a specifier for an unsigned type
you do have and cast.

1) printf("sizeof c is \"%%zu\": %zu\n", sizeof c);

2) printf("sizeof c is \"%%lu\": %lu\n", (unsigned long) sizeof c);
Apr 9 '07 #13
B. Augestad said:

<snip>
I really scared myself for a while there, unable to locate the quote
and quietly wondering if I finally had gone insane. :-)
Been there, done that, and all I got was this lousy T-shirt.
>
The sentence is in 6.5.3.4, but not in the standard. The book version
consists of two parts, the C rationale and the C standard. I looked at
the wrong part, the rationale.
And of course the Rationale is not normative, and even if it were it
wouldn't matter.
Sorry for the confusion this may have caused.
No sweat.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Apr 9 '07 #14
Harald van D?k said:

<snip>
C90 disallows a size_t greater than unsigned long.
Chapter and verse, please.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Apr 9 '07 #15
Richard Heathfield wrote:
Harald van D?k said:

<snip>
C90 disallows a size_t greater than unsigned long.

Chapter and verse, please.
size_t must be an unsigned integer type. In C90, implementation-
specific types are never integer types, even if they behave exactly
like integer types. In C99, the definition of integer types was
expanded to include implementation-defined integer types. (Sorry, no
exact C&V.)

Apr 9 '07 #16
Harald van D?k said:
Richard Heathfield wrote:
>Harald van D?k said:

<snip>
C90 disallows a size_t greater than unsigned long.

Chapter and verse, please.

size_t must be an unsigned integer type.
That depends on whether "integer type" and "integral type" are
synonymous. I can find no justification in the Standard for this claim.

Relevant quotes:

3.3.3.4:

The value of the result is implementation-defined, and its type (an
unsigned integral type) is size_t defined in the <stddef.hheader.

4.1.5:
size_t

which is the unsigned integral type of the result of the sizeof
operator;
Yeah, I know this is bleeding-edge nit-picking, and no, I know it
doesn't actually matter either way, but being proved wrong here would
nevertheless be interesting and educational, at least for me.
(Actually, so would being proved right.)

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Apr 9 '07 #17

Richard Heathfield wrote:
Harald van D?k said:
Richard Heathfield wrote:
Harald van D?k said:

<snip>

C90 disallows a size_t greater than unsigned long.

Chapter and verse, please.
size_t must be an unsigned integer type.

That depends on whether "integer type" and "integral type" are
synonymous. I can find no justification in the Standard for this claim.
They are synonymous, see DR #067.

Apr 9 '07 #18
Harald van D?k said:
>
Richard Heathfield wrote:
>Harald van D?k said:
size_t must be an unsigned integer type.

That depends on whether "integer type" and "integral type" are
synonymous. I can find no justification in the Standard for this
claim.

They are synonymous, see DR #067.
Okay, I fold. Thanks.
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Apr 9 '07 #19
"Paulo Matos" <po******@gmail.comwrites:
On Apr 9, 3:19 pm, "Harald van Dijk" <true...@gmail.comwrote:
[...]
>C90 disallows a size_t greater than unsigned long. So, you can use
this:

size_t s;
/* ... */
#if __STDC_VERSION >= 199901L
printf("%zu", s);
#else
printf("%lu", (unsigned long) s);
#endif

It's probably best put in a helper function, rather than copying the
check everywhere.

(This will not work for implementations that use C99 syntax with a C90
library. Such implementations do not conform to any standard, but are
used in the real world. Decide for yourself whether you want to
support them.)


Didn't know about zu. Those are great news. Since I'm using std=c99 to
gcc I think I'll stick with zu. Thank you!
Be careful. gcc is just a compiler; the runtime library, including
the implementation of printf, is provided separately. On some
systems, printf will support "%zu"; on others, it won't, and gcc won't
necessarily know whether "%zu" is supported or not.

In a conforming implementation, the condition
__STDC_VERSION__ >= 199901L

(Harald, you missed the trailing "__") tells you that the entire
implementation is conforming. In real life, however, __STDC_VERSION__
is set by the compiler, independently of the runtime library.

C99 *discourages*, but does not forbid, making size_t bigger than
unsigned long. In C90, you can safely use:

printf("%lu", (unsigned long)sizeof whatever);

In C99, this will work *if* sizeof whatever happens not to exceed
ULONG_MAX. This will always be true if size_t is no bigger than
unsigned long; even if size_t is bigger than unsigned long, it will be
true if the particular size you're trying to print is no bigger than
ULONG_MAX.

If you want to be paranoid, writing code that will work even with
non-conforming implementations, you can do something like this
(untested):

size_t s = whatever;
if (s (size_t)ULONG_MAX) {
printf("%zu", s);
}
else {
printf("%lu", (unsigned long)s);
}

That's not quite 100% safe either. It can fail if size_t is
*narrower* than unsigned long. It can also fail if size_t is wider
than unsigned long, but the runtime library doesn't support "%zu".

You can always write a function that converts a size_t value to a
string by brute force, without using the runtime library.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Apr 9 '07 #20
On Apr 10, 12:35 am, "B. Augestad" <b...@metasystems.nowrote:
The sentence is in 6.5.3.4, but not in the standard. The book version
consists of two parts, the C rationale and the C standard. I looked at
the wrong part, the rationale.
This wouldn't be "The Annotated C Standard", by H. Schildt, would it?

Apr 9 '07 #21
"Old Wolf" <ol*****@inspire.net.nzwrites:
On Apr 10, 12:35 am, "B. Augestad" <b...@metasystems.nowrote:
>The sentence is in 6.5.3.4, but not in the standard. The book version
consists of two parts, the C rationale and the C standard. I looked at
the wrong part, the rationale.

This wouldn't be "The Annotated C Standard", by H. Schildt, would it?
No, it's in section 6.5.3.4 of the C Rationale, revision 5.10,
published April 2003, available at
<http://www.open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf>.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Apr 9 '07 #22
B. Augestad wrote:
Richard Heathfield wrote:
>Paulo Matos said:
>>>
Is it safe to assume a size_t is an unsigned long?

Only if it is an unsigned long, which it may well not be.
>>(is it forced by the standard?)

No, the Standard only requires that size_t be an unsigned integer type
(unsigned char, unsigned short, unsigned int, unsigned long, unsigned
long long if you have it) that can represent the size of any object.
It is not even required to be a standard unsigned integer type. It
might, for example, be defined like this:

typedef unsigned __internal_27_bit_integer_type size_t;

From C99 6.5.3.4 #20 :
"This requirement implicitly restricts size_t to be a synonym for an
existing unsigned integer type".

That rules out __internal_27_bit_integer_type, doesn't it?
Why? Wouldn't __internal_27_bit_integer_type be an existing unsigned
integer type for the implementation that defines it?

--
Thad
Apr 10 '07 #23
Keith Thompson wrote:
"Paulo Matos" <po******@gmail.comwrites:
On Apr 9, 3:19 pm, "Harald van Dijk" <true...@gmail.comwrote:
[...]
C90 disallows a size_t greater than unsigned long. So, you can use
this:

size_t s;
/* ... */
#if __STDC_VERSION >= 199901L
printf("%zu", s);
#else
printf("%lu", (unsigned long) s);
#endif

It's probably best put in a helper function, rather than copying the
check everywhere.

(This will not work for implementations that use C99 syntax with a C90
library. Such implementations do not conform to any standard, but are
used in the real world. Decide for yourself whether you want to
support them.)

Didn't know about zu. Those are great news. Since I'm using std=c99 to
gcc I think I'll stick with zu. Thank you!

Be careful. gcc is just a compiler; the runtime library, including
the implementation of printf, is provided separately. On some
systems, printf will support "%zu"; on others, it won't, and gcc won't
necessarily know whether "%zu" is supported or not.

In a conforming implementation, the condition
__STDC_VERSION__ >= 199901L

(Harald, you missed the trailing "__") tells you that the entire
Oops, thanks for the correction.
implementation is conforming. In real life, however, __STDC_VERSION__
is set by the compiler, independently of the runtime library.

C99 *discourages*, but does not forbid, making size_t bigger than
unsigned long. In C90, you can safely use:

printf("%lu", (unsigned long)sizeof whatever);

In C99, this will work *if* sizeof whatever happens not to exceed
ULONG_MAX. This will always be true if size_t is no bigger than
unsigned long; even if size_t is bigger than unsigned long, it will be
true if the particular size you're trying to print is no bigger than
ULONG_MAX.

If you want to be paranoid, writing code that will work even with
non-conforming implementations, you can do something like this
(untested):

size_t s = whatever;
if (s (size_t)ULONG_MAX) {
Why the cast? It's not harmful, but I don't see the benefit myself.
printf("%zu", s);
}
else {
printf("%lu", (unsigned long)s);
}

That's not quite 100% safe either. It can fail if size_t is
*narrower* than unsigned long.
How would it fail? If you include the cast, (size_t) ULONG_MAX is
equal to SIZE_MAX, and s SIZE_MAX is always false, so it would
always print using %lu. (And if you exclude the cast, s would be
promoted, and (unsigned long) s ULONG_MAX is always false, so it
would still print using %lu.) I think you accidentally wrote better
code than you meant to. :-)
It can also fail if size_t is wider
than unsigned long, but the runtime library doesn't support "%zu".
If that's the case, even the library by itself (several library
functions have size_t parameters or return values) doesn't conform to
any C standard, even C90, right?
You can always write a function that converts a size_t value to a
string by brute force, without using the runtime library.
Apr 10 '07 #24
"Harald van Dijk" <tr*****@gmail.comwrites:
Keith Thompson wrote:
[...]
>If you want to be paranoid, writing code that will work even with
non-conforming implementations, you can do something like this
(untested):

size_t s = whatever;
if (s (size_t)ULONG_MAX) {

Why the cast? It's not harmful, but I don't see the benefit myself.
Now that you mention it, neither do I.
> printf("%zu", s);
}
else {
printf("%lu", (unsigned long)s);
}

That's not quite 100% safe either. It can fail if size_t is
*narrower* than unsigned long.

How would it fail? If you include the cast, (size_t) ULONG_MAX is
equal to SIZE_MAX, and s SIZE_MAX is always false, so it would
always print using %lu. (And if you exclude the cast, s would be
promoted, and (unsigned long) s ULONG_MAX is always false, so it
would still print using %lu.) I think you accidentally wrote better
code than you meant to. :-)
Hmm. I'm not sure why I added the cast, especially considering the
number of times here I've mentioned that most casts are useless.

*Without* the cast, the comparison (s ULONG_MAX) should give the
mathematically correct result in all cases. If it's false, then the
value of s will fit into an unsigned long, and
printf("%lu, (unsigned long)s);
will print the correct value (regardless of whether size_t is wider
than unsigned long). If it's true, then s *won't* fit in an unsigned
long, and "%zu" is the only thing that *might* work.
> It can also fail if size_t is wider
than unsigned long, but the runtime library doesn't support "%zu".

If that's the case, even the library by itself (several library
functions have size_t parameters or return values) doesn't conform to
any C standard, even C90, right?
Right, though the failure to support "%zu" might be the only point of
non-conformance to C99.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Apr 10 '07 #25

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

7 posts views Thread by William Xuuu | last post: by
5 posts views Thread by Old Wolf | last post: by
23 posts views Thread by bwaichu | last post: by
27 posts views Thread by pkirk25 | last post: by
22 posts views Thread by subramanian100in | last post: by
73 posts views Thread by Yevgen Muntyan | last post: by
9 posts views Thread by Bob Cassel | last post: by
8 posts views Thread by lubomir dobsik | last post: by
50 posts views Thread by jacek.dziedzic | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by harlem98 | last post: by
1 post views Thread by Geralt96 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.