eyalroz/printf

I'd like %I64d to print int64_t, even it's not standard.

Closed this issue · 21 comments

My company aways use fixed int type . It's very disgusting to use "%" PRI64d "".

I certainly agree that it's annoying and unintuitive to write "%" PRI64d "".

Tell me, though...

  • Which compilers support this?
  • Where is the exact specification of how this behaves?
  • How widely used do you believe this is?

Finally, I would want the opinion of some other people about such a feature, even if I implement it as off-by-default.

edit: Found the MSVC specification. That's a bit problematic. You see, it only supports I32 and I64. If we were to go for this, we would definitely want to have and I8 and I16 as well, right?

use Preprocessor to select

  1. msvc mode only I32 I64
  2. all 8,16,32,64.

@superzmy: Can you answer the rest of my questions though?

@mickjc750 , what do you think?

@superzmy : ping.

@mickjc75 : also ping.

So far the GNU printf() has been the benchmark. I'd recommend keeping it that way.

@mickjc750 : Well, there's a positive and a negative aspect of it being a benchmark. Any valid format string for GNU printf is a valid format string for us (ignoring %a and long-long-double which we haven't implemented yet). But a malformed format GNU print format string being rejected by us as well has not been a principle of mine...

Let me put it to you this way: Suppose you could make this change in GNU printf as well. Would you have it support %i8, ... %i64?

@eyalroz yes I would. I agree that it's better than PRI64d.

@mickjc750 : So why not offer this as an optional feature? It can even default to OFF, so that positive-and-negative GNU printf compatibility is maintained by default.

@eyalroz I see it as non-portable feature creep. Although I'm probably biased as I'm always in Debian.

I'm for this change. PRI64d is a mess.

@JakeSays : And what would you respond to mickjc750's claim that it's "non-portable feature creep"?

@eyalroz First, it's not "feature creep" if we as a community decide that it adds value. Secondly, if MSVC wasn't important then clang wouldn't have implemented compatibility for its syntax.

if MSVC wasn't important then clang wouldn't have implemented compatibility for its syntax.

It does? Can I have a link to that?

@JakeSays : So, %I64 is supported with -fms-extensions?

Well, I think I'm sold. Let's add the %I format specifiers for 64, 32, 16 and 8. I will make them optional features though!

@JakeSays , @mickjc750 , @superzmy : Please have a look at PR #83 .

@superzmy : Please give the development branch a spin using %I64d -style specifiers...

I don't understand what this means
【The I specifier is not in the C (nor C++) standard, but is somewhat popular, as it makes it easier to handle integer types of specific size. One must specify the argument size in bits immediately after the I: I8 for int8_t, I16 for int16_t, I32 for int32_t, I64 for int64_t. The printing is "integer-promotion-safe", i.e. the fact that an int8_t may actually be passed in promoted into a larger int will not prevent it from being printed using its origina value.
There is no unsigned equivalent of the I specifier at the moment.】
Usually we write "%I64d %I64u %I64x" in MSVC format. 'I' means signed or unsigned integer type, other than float type

@superzmy : Oh, sorry, I didn't update the documentation. Updated it now.

Can you please add #defines to compile-out this behavior for users who don't need it? It generates a ton of warnings for with Clang, and I don't want to disable -Wformat because it is useful for actual formatting problems (from develop branch)

../printf/test/test_suite.cpp:566:67: warning: length modifier 'I64' results in undefined behavior or no effect with 'u' conversion specifier [-Wformat]
  PRINTING_CHECK("          4294966272", ==, sprintf_, buffer, "%*I64u", 20, (uint64_t) 4294966272U);

@phillipjohnston Oh, I forgot the defines in the test suite... I'll fix that, of course.