Platform independent size_t Format specifiers in c?
Asked Answered
D

3

106

I want to print out a variable of type size_t in C but it appears that size_t is aliased to different variable types on different architectures. For example, on one machine (64-bit) the following code does not throw any warnings:

size_t size = 1;
printf("the size is %ld", size);

but on my other machine (32-bit) the above code produces the following warning message:

warning: format '%ld' expects type 'long int *', but argument 3 has type 'size_t *'

I suspect this is due to the difference in pointer size, so that on my 64-bit machine size_t is aliased to a long int ("%ld"), whereas on my 32-bit machine size_t is aliased to another type.

Is there a format specifier specifically for size_t?

Desirae answered 24/1, 2010 at 3:47 Comment(5)
Your warning message does not match the code. The warning mentions pointers, your code doesn't have any. Did you remove some & somewhere?Normi
Pointers? No I don't get any warnings about pointers, in fact depending on what machine I run that code on sometimes I get no warnings at all. Try the following test code: #include <stdio.h> int main(){ size_t size = 1; printf("the size is %ld", size); return 0; }Desirae
See also Cross platform format string for variables of type size_t?.Bistort
@EthanHeilman He's referring to the fact that your warnings say warning: format '%ld' expects type 'long int *', but argument 3 has type 'size_t *' when it probably should be saying warning: format '%ld' expects type 'long int', but argument 3 has type 'size_t'. Were you maybe using scanf() instead when you got these warnings?Gadfly
Possible duplicate of What's the correct way to use printf to print a size_t?Rapids
F
143

Yes: use the z length modifier:

size_t size = sizeof(char);
printf("the size is %zu\n", size);  // decimal size_t ("u" for unsigned)
printf("the size is %zx\n", size);  // hex size_t

The other length modifiers that are available are hh (for char), h (for short), l (for long), ll (for long long), j (for intmax_t), t (for ptrdiff_t), and L (for long double). See §7.19.6.1 (7) of the C99 standard.

Forgive answered 24/1, 2010 at 3:49 Comment(6)
whats the difference between zd and zu? I get that zd is decimal, but is it signed, if so how does zd being signed effect things.Desirae
It's the difference between a size_t and an ssize_t; the latter is seldomly used.Forgive
Right, so in this case, you should be using %zu, because the argument is unsigned.Edmea
The other options available are explained in the printf manual page: linux.die.net/man/3/printfAcclaim
Is this also part of C89/90?Bostow
@detly: No, the z length modifier is not part of C89/C90. If you're aiming for C89-compliant code, the best you can do is cast to unsigned long and use the l length modifier instead, e.g. printf("the size is %lu\n", (unsigned long)size);; supporting both C89 and systems with size_t larger than long is trickier and would require using a number of preprocessor macros.Forgive
C
53

Yes, there is. It is %zu (as specified in ANSI C99).

size_t size = 1;
printf("the size is %zu", size);

Note that size_t is unsigned, thus %ld is double wrong: wrong length modifier and wrong format conversion specifier. In case you wonder, %zd is for ssize_t (which is signed).

Commode answered 1/3, 2014 at 13:24 Comment(0)
S
1

MSDN, says that Visual Studio supports the "I" prefix for code portable on 32 and 64 bit platforms.

size_t size = 10;
printf("size is %Iu", size);
Sacred answered 14/10, 2015 at 19:3 Comment(2)
it's MS specific, which is not standard conforming, so it's not platform independentRapids
@Rapids Indeed. And if it really does say - as the answer suggests - 'portable' it's even worse than I ever knew about MS. Not that it would surprise me... I'm not one to downvote because someone went through the effort to try and answer something but still this answer is just wrong. Ah, I think I understand the idea here in 'portable'. It must be saying that it works for both 32-bit and 64-bit. But of course it would.Drumm

© 2022 - 2024 — McMap. All rights reserved.