2

My company is moving from C slowly to C++98. C++98 is a superset of C so this shouldn't be a problem, but it is. Printing 64-bit fixed-width integers using printf does not work when used in combination with pedantic, warning flags, and specifying code for a 32-bit environment.

The numbers I need to print are of type uint64_t. And I understand usage of PRIX64 when using printf. However, as soon as the extra flags are added when compiling, errors ensue.

I've looked at the headers to see if there's anything weird, but it all looks good. I'm not sure why using this combination works in C but not C++. Of course the correct way to solve this would be to start using std::cout, but there's so much code to edit, it's not feasible to do it all at once.

Minimal example shown below (print.cpp):

#include <stdio.h>

#define __STDC_FORMAT_MACROS
#include <inttypes.h>

int main()
{
  uint64_t num = 0x0;
  printf("num is %" PRIX64"\n", num);

  return 0;
}

command used to compile it:

g++ print.cpp -o print  --std=c++98 -Wall -m32 --pedantic

Expected result: no errors, number is printed. Result:

warning: ISO C++ does not support the ‘ll’ gnu_printf length modifier
phuclv
  • 37,963
  • 15
  • 156
  • 475
kill -9
  • 159
  • 1
  • 9
  • Similar to https://stackoverflow.com/questions/54649040/how-do-i-suppress-the-iso-c-does-not-support-int128-warning – racraman May 02 '19 at 22:34
  • 4
    C++98 is *not* a superset of C, though the two have a common subset large enough to program in. – John Bollinger May 02 '19 at 22:34
  • What happens if you use "%lu" (for unsigned longs) and "%li" instead of "%llu" or "%lli"? – Alecto Irene Perez May 02 '19 at 22:35
  • 3
    C++98 is not really a superset of any version of C. And the C library interfaces which are part of the C++98 standard C library are a *subset* of the C99 library. But neither `stdio.h` nor `inttypes.h` are part of the C++ standard. You should be using `cstdio` and `cinttypes`. (But that might not make any difference.) – rici May 02 '19 at 22:38
  • 2
    The warning means what it says. `PRIX64` is from C99. Of course C++98 doesn't support C features that were only standardised a year later. C++11 has some compatibility-with-C mandates that C++98 doesn't have, including these macros. – Cubic May 02 '19 at 22:40
  • 1
    Honestly, if it's at all possible to use C++11 that's what I'd go for. C++11 has some major quality-of-life improvements that make it easier to write c++ code, and it also introduces move semantics and smart pointers (which make it easier to avoid copying large blocks of data while still writing sensible code) – Alecto Irene Perez May 02 '19 at 23:01
  • why don't just move to at least C++11? – phuclv May 03 '19 at 01:22

1 Answers1

2

C++98 does not have uint64_t or PRIX64 (nor llx). Those were introduced to C++ in C++11 (side-note: They are not in C either until C99 standard).

Those macros may happen to work by coincidence, since they are provided by the standard library which presumably has support for newer standard, and doesn't go out of its way to prevent older code from using the new features. But they are not guaranteed to work

The compiler appears to not warn about macros presumably because the implementers were not exited about instrumenting the pre-processor to perform such diagnostics. But the compiler is friendly enough to diagnose the usage of a non-standard printf specifier (The llx specifier which PRIX64 macro expands to on your target system).

eerorika
  • 232,697
  • 12
  • 197
  • 326