143

I wrote a very simple test code of printf uint64_t:

#include <inttypes.h>
#include <stdio.h>

int main()
{
  uint64_t ui64 = 90;
  printf("test uint64_t : %" PRIu64 "\n", ui64);
  return 0;
}

I use ubuntu 11.10 (64 bit) and gcc version 4.6.1 to compile it, but failed:

main.cpp: In function ‘int main()’:
main.cpp:9:30: error: expected ‘)’ before ‘PRIu64’
main.cpp:9:47: warning: spurious trailing ‘%’ in format [-Wformat]
Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
Dan
  • 3,221
  • 7
  • 27
  • 24
  • 1
    It seems that you are compiling C code as C++, that is your error. If you rename your file to `main.c` and compile it with gcc, all should work fine. – Jens Gustedt Nov 15 '11 at 08:06
  • Same without error: http://stackoverflow.com/questions/9225567/how-to-print-a-int64-t-type-in-c – Ciro Santilli OurBigBook.com Mar 08 '17 at 14:09
  • With either gcc or clang, it’s a good idea to specify `-std=c11` or the version of the standard you’re using. That catches this and other errors. I also recommend `-Wall -Wextra -Wpedantic -Wconversion` at least. – Davislor Dec 16 '18 at 02:10

3 Answers3

178

The ISO C99 standard specifies that these macros must only be defined if explicitly requested.

#define __STDC_FORMAT_MACROS
#include <inttypes.h>

... now PRIu64 will work
Will
  • 73,905
  • 40
  • 169
  • 246
  • Thanks for your reminder. stackoverflow only allows me to accept the answer after a few minutes. By the way, for other reader about lld and PRIu64, please visit: http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml item:64-bit Portability Thanks you all again! – Dan Nov 15 '11 at 07:00
  • 11
    Hm, just including the header should suffice. The `__STDC_FORMAT_MACROS` macro is only required for inclusion in C++. – Jens Gustedt Nov 15 '11 at 08:05
  • And this is actually the answer, Dan was just compiling his code with the wrong compiler. – Jens Gustedt Nov 15 '11 at 08:07
  • or not -std=c99 or any other small detail – Will Nov 15 '11 at 08:13
  • 17
    @Jens: Indeed; `__STDC_FORMAT_MACROS` appears only in a footnote in C99, suggesting that C++ only define these macros in the presence of the request. However the C++ committee chose to ignore the suggestion: e.g. in the n3242 draft, 27.9.2/3: _Note: The macros defined by are provided unconditionally. In particular, the symbol __STDC_FORMAT_MACROS, mentioned in footnote 182 of the C standard, plays no role in C++._ So when the compilers catch up, we won't need `__STDC_FORMAT_MACROS` in either C or C++. – John Marshall Nov 15 '11 at 08:31
  • 3
    @John Marshall g++ 4.7.3 seems to require the macro, even when is included. – crockeea Oct 31 '13 at 03:27
  • 4
    @Eric: Apparently g++ 4.7.3 hadn't caught up! In fact, probably you are using it with a glibc version that predates [this bug fix](http://sourceware.org/bugzilla/show_bug.cgi?id=15366). As discussed in that glibc report, your g++ 4.7.3's libstdc++ has code to work around this problem. If you compile with `-std=c++0x` and perhaps #include rather than , I believe it'd provide the format macros without you supplying `__STDC_FORMAT_MACROS`. – John Marshall Oct 31 '13 at 15:57
  • Also works for PRIu32, just for keyword searching sake :) – Lazik Jul 19 '15 at 13:34
  • ISO C99 doesn't specify anything about `__STDC_FORMAT_MACROS`. It's only mentioned in a footnote (and that footnote was removed in C11). In C99 and C11, `#include ` must define the format macros. – M.M Jul 04 '16 at 21:21
  • 1
    @JohnMarshall It actually seems that the footnote still does apply to ``, but is overruled by the C++ standard for ``, since the note in the C++ standard doesn't mention ``, only `` (which doesn't exist with this name in C). I suppose you still do have to use `__STDC_FORMAT_MACROS`, since the standard is not too clear — and may be interpreted differently by implementations. – Ruslan Apr 25 '17 at 12:47
  • @Ruslan: What footnote? As M.M noted, it's gone in C11 — `__STDC_FORMAT_MACROS` no longer appears in the C standard. Agreed though that this probably remains a mess in implementations… Perhaps the glib answer to all this is that it's immaterial in C++: if you're using `<<` and `>>` you surely have no interest in these _inttypes_ macros that are only for use with `printf`/`scanf`. – John Marshall Apr 25 '17 at 13:17
  • 1
    @JohnMarshall I agree that they are almost useless in C++. I even learned about the mess only when I tried to compile a C++ library which used `inttypes.h` with `PRIxLEAST64` and didn't define this macro — which doesn't compile with my particular glibc version. – Ruslan Apr 25 '17 at 16:28
  • This answer should be edited to include the information from the comments below it. It seems very outdated. – paleonix Apr 15 '23 at 02:37
4

When compiling memcached under Centos 5.x i got the same problem.

The solution is to upgrade gcc and g++ to version 4.4 at least.

Make sure your CC/CXX is set (exported) to right binaries before compiling.

tshepang
  • 12,111
  • 21
  • 91
  • 136
3

Since you've included the C++ tag, you could use the {fmt} library and avoid the PRIu64 macro and other printf issues altogether:

#include <fmt/core.h>

int main() {
  uint64_t ui64 = 90;
  fmt::print("test uint64_t : {}\n", ui64);
}

The formatting facility based on this library is proposed for standardization in C++20: P0645.

Disclaimer: I'm the author of {fmt}.

vitaut
  • 49,672
  • 25
  • 199
  • 336
  • Cool! Is it coming also something similar to `sscanf`? – ceztko Nov 27 '19 at 21:28
  • 1
    Quite possibly. We are investigating the possibility of replacing `scanf`. – vitaut Nov 28 '19 at 00:18
  • Great! Also I wonder if there are progress towards a locale independent and/or locale selectable version of [`std::to_string()`](https://en.cppreference.com/w/cpp/string/basic_string/to_string). The cppreference page still link only to [`std::to_chars()`](https://en.cppreference.com/w/cpp/utility/to_chars), which is not really what people need. I wonder if `fmt` and/or c++20 deal with it or not yet. – ceztko Nov 28 '19 at 00:28
  • `std::to_string` will probably remain as is, but `std::format` allows you to control whether to use locale or not (and by default it doesn't use the locale). – vitaut Nov 28 '19 at 01:26