Martin Storsjö wrote:
On Fri, 17 Feb 2023, Christian Franke wrote:

When compiling this on MSYS2 UCRT64 with current mingw-w64-ucrt-x86_64-gcc 12.2.0-10, gcc and g++ results differ:

#include <stdint.h>
#include <stdio.h>

#if !(defined(_UCRT) && !__USE_MINGW_ANSI_STDIO)
#warning unexpected configuration
#endif

void f(size_t s, uint64_t u)
{
  // gcc: No warning
  // g++: "unknown conversion type character 'z' ..."
  printf("%zu", s);
  // gcc: "format '%u' expects argument of type 'unsigned int', ..."
  // g++: No warning
  printf("%I64u", u);
}

This shows that gcc defaults to format 'gnu_printf' but g++ defaults to format 'ms_printf'.

Is this difference intentional, a MSYS2 packaging issue (i.e. wrong build parameters, incomplete local patch, ...) or a GCC upstream bug?

Would not be a problem if gcc/g++ would allow to override this attribute for its builtins.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95130

That's indeed weird. It looks to me like this is possibly another case/variant of the linked bug.

By preprocessing the source file with -E, it looks to me like the printf function does end up declared with gnu_printf format in both cases anyway - so with that in mind, it should be consistent - but perhaps intricacies of that bug makes it only happen in one language mode but not in the other one.


The test below shows that the __attribute__ ((__nonnull__ (1))) from the expanded prototype makes a difference. If specified, the default format ms_printf is overridden, but only if gcc is used. The builtin is still active for code generation as the printf() -> puts() optimization is still done.

#ifdef __cplusplus
extern "C" {
#endif

typedef unsigned long long uint64_t;
typedef unsigned long long size_t;

__attribute__((__format__(gnu_printf,1,2)))
#ifdef NN
// gcc: gnu_printf, g++: ms_printf
__attribute__ ((__nonnull__ (1)))
#else
// gcc/g++: ms_printf
#endif
int __attribute__((__cdecl__)) printf(const char * __restrict__ _Format,...);

#ifdef __cplusplus
}
#endif

void f(size_t s, uint64_t u)
{
  printf("%zu", s);
  printf("%I64u", u);
  printf("Text\n"); // always generates puts("Text");
}



_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to