Compiler warning on mix of "stdio.h" and <cstdio>

413 Views Asked by At

The following program results in compiler warnings if the include statement in line 4 is added (uncommented).

Compiler: gcc version 8.1.0 (i686-win32-dwarf-rev0, Built by MinGW-W64 project)

#define __STDC_FORMAT_MACROS

// Adding this and -Wall results in compiler warning
//#include "stdio.h"

#include <cstdint>
#include <cinttypes>
#include <cstdio>

int main()
{
    int64_t i     = 0;
    printf("%" PRId64, i);
}

The warnings are:

testlld.cpp:11:14: warning: unknown conversion type character 'l' in format [-Wformat=]
  std::printf("%" PRId64, i);
              ^
testlld.cpp:11:14: warning: too many arguments for format [-Wformat-extra-args]
testlld.cpp:11:14: warning: unknown conversion type character 'l' in format [-Wformat=]
testlld.cpp:11:14: warning: too many arguments for format [-Wformat-extra-args]

Can someone explain what happens?

I can of course fix this by using only <cstdio>, which would be the correct thing in this case.

But it leads to another question...

Say I have a header file that is included by two implementation files - one compiled with a C compiler and one compiled with a C++ compiler. The header file would need to use "stdio.h" since it needs to compile with a C compiler. Does this mean that all code including that header file must also use "stdio.h" and NOT <cstdio>, even if it is C++ code?

2

There are 2 best solutions below

2
nielsen On

This seems to be a known bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60434

This makes sense since - despite the warning - the 64 bit integer is printed correctly.

By the way, when compiling as C (changing the included headers to .h), the format string defined by PRId64 is I64d. Using this format string gives no warning neither when compiling as C nor as C++. Hence a possible workaround is to use

    printf("%I64d", i);

Another option is to build with -D__USE_MINGW_ANSI_STDIO.

3
jgreen81 On

Following the suggestions above, I did the following, which compiles without warnings.

// Needed to define the macros for data types in inttypes.h
#define __STDC_FORMAT_MACROS

// This part in header file (.h) re-used by this file as well as .c files compiled with C compiler
#ifdef __cplusplus
#include <cstdio>
#else
#include "stdio.h"
#endif

#include <cstdint>
#include <cinttypes>
#include <cstdio>

int main()
{
    int64_t i     = 0;
    printf("%" PRId64, i);
}

This looks like a good (the right?) solution for me.