Correct printf format specifier for size_t: %zu or %Iu?
Asked Answered
C

4

59

I want to print out the value of a size_t variable using printf in C++ using Microsoft Visual Studio 2010 (I want to use printf instead of << in this specific piece of code, so please no answers telling me I should use << instead).

According to the post

Platform independent size_t Format specifiers in c?

the correct platform-independent way is to use %zu, but this does not seem to work in Visual Studio. The Visual Studio documentation at

http://msdn.microsoft.com/en-us/library/vstudio/tcxf1dw6.aspx

tells me that I must use %Iu (using uppercase i, not lowercase l).

Is Microsoft not following the standards here? Or has the standard been changed since C99? Or is the standard different between C and C++ (which would seem very strange to me)?

Crewel answered 25/3, 2013 at 7:53 Comment(2)
The MSDN page you linked to says The I, I32, and I64 length modifier prefixes are Microsoft extensions and are not ANSI-compatible, which seems to answer your question about MS following standards.Aspasia
#1547289Dortheydorthy
S
26

MS Visual Studio didn't support %zu printf specifier before VS2013. Starting from VS2015 (e.g. _MSC_VER >= 1900) %zu is available.

As an alternative, for previous versions of Visual Studio if you are printing small values (like number of elements from std containers) you can simply cast to an int and use %d:

printf("count: %d\n", (int)str.size()); // less digital ink spent
// or:
printf("count: %u\n", (unsigned)str.size());
Sit answered 18/5, 2017 at 18:20 Comment(3)
If you're targeting C++, I would use static_cast in preference to a C-style cast. It has the primary advantage that it's checked at compile-time.Tetzel
Reference: learn.microsoft.com/en-us/cpp/c-runtime-library/…Micra
Does VS2013 actually support %zu? Isn’t it only available since VS2015? The VS2013 documentation for printf size specifiers says %z is not supported, and the link in this answer leads to documentation for VS2015 (with vs-2015 in the URL), not VS2013.Incompletion
H
15

Microsoft's C compiler does not catch up with the latest C standards. It's basically a C89 compiler with some cherry-picked features from C99 (e.g. long long). So, there should be no surprise that something isn't supported (%zu appeared in C99).

Hyponitrite answered 25/3, 2013 at 7:57 Comment(1)
MSVC has been focused on C++ conformance and not C in the past, although that's changing. Since the C99 Standard Library was added to the C++11 Standard Library by reference, CRT work started back in VS 2013. z wasn't added until VS 2015. The other main issue is that the C99 preprocessor was declared part of the C++ Standard, so this work has been on-going and will be complete in VS 2019 16.6.Prelect
T
14

The Microsoft documentation states:

The hh, j, z, and t length prefixes are not supported.

And therefore %zu is not supported.

It also states that the correct prefix to use for size_t is I – so you'd use %Iu.

Tessietessier answered 11/12, 2013 at 20:21 Comment(3)
VS 2015 supports %zPrelect
@ChuckWalbourn the current link has a timestamp from 2017 and it says %z isn't supported. Was z support removed in a subsequent version?Abe
%zu definitely works in VS 2015. See Microsoft Docs. Your link is the old MSDN docs which haven't been maintained in a long time.Prelect
M
5

Based on the answer from here, %z is a C99 addition. Since MSVC doesn't support any of the later C standards, it's no surprise that %z isn't supported.

Mowry answered 25/3, 2013 at 7:58 Comment(7)
Somewhere (I don't have the reference unfortunately) MS said that they will never support C99.Terriss
@john: see e.g. herbsutter.com/2012/05/03/reader-qa-what-about-vc-and-c99. Their compiler is called Visual C++, ever since version 1.0, and in contrast with their DOS-age "Microsoft C/C++ compiler".Gloria
VS 2015 supports C99. Both 2013 and 2015 support %zu.Rundgren
VS2013 does not support %zu, only %Iu. Can't speak for 2015.Hensel
@JustinM.Keyes 2015 doesn't support "C99". They like to pretend they do by having just enough library support to build things like ffmpeg, but they sure do not speak the actual language. Try designated initializers some day.Eleemosynary
@LarsViklund: You may want to recheck in C mode. MSVC++ 2015 doesn't support them in C++ mode, which is correct. But %zu is another matter, because C++11 picked up the C99 library changes. %zu must now work in either mode.Gloria
@JustinM.Keyes I've tested in Visual Studio 2013 update 5, however it does not recognize %zu in printf function. Neither .c nor .cpp files.Lynwoodlynx

© 2022 - 2024 — McMap. All rights reserved.