Assuming size_t is unsigned long

O

Old Wolf

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?
 
T

Thad Smith

B. Augestad said:
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?
 
G

Guest

Keith said:
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?
 
K

Keith Thompson

Harald van Dijk said:
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.
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.
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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,147
Latest member
CarenSchni
Top