7

In cplusplus.com reference for printf I see a specification for a "length" formatting, but it includes the note:

Yellow rows indicate specifiers and sub-specifiers introduced by C99. See <cinttypes> for the specifiers for extended types.

My question is specifically on the hh length formatting. And it's a "yellow" row. Formatting with hh behaves as expected in Visual Studio, but I'm wondering whether that's because Visual Studio is also C compiler or because hh actually supported by C++?

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
Jonathan Mee
  • 37,899
  • 23
  • 129
  • 288
  • [`std::printf`](http://en.cppreference.com/w/cpp/io/c/fprintf) is fully supported and generally follows the C standard. Not that I recommend you to use it though, why do you need it in C++ where you have the type-safe `std::cout` which don't need such formatting hints? – Some programmer dude Aug 14 '15 at 11:43
  • 2
    Since printf format strings are interpreted at runtime, the call cannot fail to compile. Of course, many compilers attempt to issue warnings about incorrect format strings, and you might be referring to the absence of such a warning. Whether hh is handled depends on the standard library implementation. – rici Aug 14 '15 at 12:01
  • @rici That's an excellent point. I know that the format string is run-time interpreted, but I often forget that. I will edit the question. – Jonathan Mee Aug 14 '15 at 12:23
  • VC is **no** standard-compliant C compiler. It is not even compatible with the previous standard, but that is just 16 years old, so maybe in 10 years ... (IIRC there are actually unsupported _length modifiers_.) – too honest for this site Aug 14 '15 at 14:33
  • @Olaf As the answers have pointed out it wasn't until C++11 that C++ incorporated C99. So perhaps correctly Visual Studio hasn't supported it. [The `hh` formatting, specifically, isn't fully supported until Visual Studio 2015.](http://stackoverflow.com/questions/32009189/c-support-for-length-specifiers?noredirect=1#comment51922917_32009255) – Jonathan Mee Aug 14 '15 at 14:51
  • @JonathanMee: "... because Visual Studio is also C compiler ..." That's what I obviously refer to. I'm **not** talking about C++, as that is a **different** language which is not compatible to C (no superset). – too honest for this site Aug 14 '15 at 15:11

2 Answers2

5

The C++ standard used C90 as a normative reference until C++11 and so C99 features would only be supported in C++11. Although a compiler would be free to support them outside of C++11 as an extension. I would suspect this would only work with more recent versions of Visual Studio given their relatively recent drive to support C99 and cremno indicates that it is supported since 2015.

If we go to the C++11 draft standard section 1.2 Normative references [intro.refs] it says:

The following referenced documents are indispensable for the application of this document. For dated references, only the edition cited applies. For undated references, the latest edition of the referenced document (including any amendments) applies.

and includes:

  • ISO/IEC 9899:1999, Programming languages — C

and also says:

The library described in Clause 7 of ISO/IEC 9899:1999 and Clause 7 of ISO/IEC 9899:1999/Cor.1:2001 and Clause 7 of ISO/IEC 9899:1999/Cor.2:2003 is hereinafter called the C standard library.1

prior to C++11 this was:

  • ISO/IEC 9899:1990, Programming languages - C

and if we try an example in gcc using -std=c++03 -pedantic it warns:

warning: ISO C++98 does not support the 'hh' gnu_printf length modifier [-Wformat=]

Community
  • 1
  • 1
Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
3

If you keep reading down the page

Those listed here are supported by the latest C and C++ standards (both published in 2011), but those in yellow were introduced in C99 (only required for C++ implementations since C++11)

So if you have Visual Studio 2013 or later, you will have access to (most) C++11 features.

Cory Kramer
  • 114,268
  • 16
  • 167
  • 218
  • Of course the answer would be hidden on the same page I link to. Thanks for reading where I failed. – Jonathan Mee Aug 14 '15 at 11:45
  • 2
    `hh` in particular is only supported since [2015](http://blogs.msdn.com/b/vcblog/archive/2014/06/18/crt-features-fixes-and-breaking-changes-in-visual-studio-14-ctp1.aspx). – cremno Aug 14 '15 at 12:00
  • @cremno I can locally confirm that `hh` works fine circa Visual Studio 2010+. – Jonathan Mee Aug 14 '15 at 12:21
  • @JonathanMee: I guess it just accidentally works. Can you look at the source code? [MSDN](https://msdn.microsoft.com/en-us/library/tcxf1dw6%28v=vs.120%29.aspx) also says `hh` isn't supported. – cremno Aug 14 '15 at 12:25
  • @cremno I've just run this on Visual Studio 2010 and it prints 106: `#include void main() { const unsigned char foo = 'j'; printf("%hhu", foo); }` – Jonathan Mee Aug 14 '15 at 12:42
  • 2
    I've looked at it myself and it accidentally works. `hh` is interpreted as two `h` (for `short int`!) but I have to say I don't see how it could break in practice (except with `%n` or `scanf()`). Don't rely on it and use 2015 if `hh` support is needed. – cremno Aug 14 '15 at 12:42
  • @cremno Perhaps that's the issue they fixed? I am not trying to use this on `scanf` but that is undefined behavior to write a `short` to the address of a `char`. – Jonathan Mee Aug 14 '15 at 12:46
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/86999/discussion-between-jonathan-mee-and-cremno). – Jonathan Mee Aug 14 '15 at 13:19