ChatGPT解决这个技术问题 Extra ChatGPT

Platform independent size_t Format specifiers in c?

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?

Your warning message does not match the code. The warning mentions pointers, your code doesn't have any. Did you remove some & somewhere?
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 int main(){ size_t size = 1; printf("the size is %ld", size); return 0; }
@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?

a
anatolyg

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.


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.
It's the difference between a size_t and an ssize_t; the latter is seldomly used.
Right, so in this case, you should be using %zu, because the argument is unsigned.
The other options available are explained in the printf manual page: linux.die.net/man/3/printf
@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.
m
maxschlepzig

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).


A
Arkantos

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);

it's MS specific, which is not standard conforming, so it's not platform independent
@phuclv 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.

关注公众号,不定期副业成功案例分享
Follow WeChat

Success story sharing

Want to stay one step ahead of the latest teleworks?

Subscribe Now