Weird result from size_t

R

Rui Maciel

It's expected that size_t is an unsigned integral type and therefore it has been suggested that (size_t)-1 is
a good, standard-ish way to determine the maximum value representable by a size_t. So I ran the following
code:

<code>
#include <stdio.h>

int main(void)
{
printf("size: %zd\n", (size_t)-1);
return 0;
}
</code>

What I didn't expected was the following output:

<shell>
525 rui@kubuntu:temp$ gcc main.c
526 rui@kubuntu:temp$ ./a.out
size: -1

</shell>


Is this a GCC bug or am I missing out something?


Rui Maciel
 
J

jacob navia

Rui Maciel a écrit :
It's expected that size_t is an unsigned integral type and therefore it has been suggested that (size_t)-1 is
a good, standard-ish way to determine the maximum value representable by a size_t. So I ran the following
code:

<code>
#include <stdio.h>

int main(void)
{
printf("size: %zd\n", (size_t)-1);
return 0;
}
</code>

What I didn't expected was the following output:

<shell>
525 rui@kubuntu:temp$ gcc main.c
526 rui@kubuntu:temp$ ./a.out
size: -1

</shell>


Is this a GCC bug or am I missing out something?


Rui Maciel

Using lcc-win (gcc should be the same)

#include <stdio.h>

int main(void)
{
printf("size: %zd\n", (size_t)-1);
printf("size: %zu\n", (size_t)-1);
return 0;
}

Output:
size: -1
size: 4294967295
 
S

Seebs

It's expected that size_t is an unsigned integral type and therefore it has been suggested that (size_t)-1 is
a good, standard-ish way to determine the maximum value representable by a size_t. So I ran the following
code:

Hee hee.
printf("size: %zd\n", (size_t)-1);

%zd prints a *signed* value of the same size as a size_t.

Try %zu.

-s
 
R

Rui Maciel

jacob said:
Using lcc-win (gcc should be the same)

#include <stdio.h>

int main(void)
{
printf("size: %zd\n", (size_t)-1);
printf("size: %zu\n", (size_t)-1);
return 0;
}

Output:
size: -1
size: 4294967295

Nice. I see it does in fact work. Thanks for the help, everyone.


Rui Maciel
 
K

Keith Thompson

jacob navia said:
Using lcc-win (gcc should be the same)

#include <stdio.h>

int main(void)
{
printf("size: %zd\n", (size_t)-1);
printf("size: %zu\n", (size_t)-1);
return 0;
}

Output:
size: -1
size: 4294967295

Strictly speaking, the behavior of
printf("size: %zd\n", (size_t)-1);
is undefined. It expects a value of the signed integer type
corresponding to size_t, but you're giving it a value of type
size_t, and a value that's outside the representable range of the
signed type.

In practice, you're very likely to get the "-1" output you're
seeing. You're *converting* the int value -1 to size_t, and then
*reinterpreting* the resulting bit pattern as if it were of a signed
type. On most systems, the conversion and the reinterpretation
will be inverse operations (I'm glossing over the fact that int
and size_t could be different sizes, but the result is the same).

There are cases where you can get away with using a printf format
that doesn't exactly match the type of the argument, but I find
it much easier to be consistent (using casts if necessary) than to
figure out the cases where you don't have to be.
 
P

Peter Nilsson

Seebs said:
%zd prints a *signed* value of the same size as a size_t.

Strictly speaking, it expects and prints the corresponding
signed type for size_t. There may be multiple signed integer
types with the same 'size' as size_t, but %zd isn't
guaranteed to work for them.
 

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,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top