This makes things closer match how this works in MSVC.
A few minor details still differ though: In MS UCRT headers,
the __local_stdio_{printf,scanf}_options functions are inline
in the public headers. I don't see any technical advantage in
doing that (and getting that kind of inline correct in C is tricky).
This makes it possible to set the flags at runtime, by assigning
to _CRT_INTERNAL_LOCAL_PRINTF_OPTIONS. This also makes it
possible to affect the flags of our non-inline UCRT stdio
functions, like stdio/ucrt_printf.c and similar ones.
In MSVC, these flags are adjustable in many different ways. I
haven't found any docs that explicitly describe which mechanisms
are intended to be used, and which ones should be avoided:
1. One can define e.g. _CRT_INTERNAL_LOCAL_PRINTF_OPTIONS to a
different constant value while compiling. In MSVC, this does
affect all functions (as all are defined inline in headers).
In the mingw-w64 headers, this only affects the functions that
are defined inline (currently mostly the wide char functions).
2. One can assign to e.g. _CRT_INTERNAL_LOCAL_PRINTF_OPTIONS at
runtime. Previously this wasn't supported in mingw-w64, now it
becomes supported. Doing this now affects the non-inline functions
too.
3. In MSVC, one can define _CRT_STDIO_ISO_WIDE_SPECIFIERS or
_CRT_STDIO_LEGACY_WIDE_SPECIFIERS while compiling. This adds
directives, pulling in an extra library, which adds a constructor
function, which on startup sets or clears bits in
_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, depending on the choice.
This is the mechanism that is closest to being documented (it
was mentioned in a blog post [1], although the behaviour change
advertised in that blog post was later reverted before release).
We currently don't have anything corresponding to this.
4. One can also call e.g. __local_stdio_printf_options directly
and assign to it. We should now be fully compatible with this.
It's unclear how many projects attempt to do any of this at all;
if they do, it's probably most plausible that they do 3 or 2.
In MSVC, the options flags are statically initialized to zero,
while another startup routine
(__scrt_initialize_default_local_stdio_options) sets their initial
values. Here we just statically initialize them to their default
values.
[1]
https://devblogs.microsoft.com/cppblog/c-runtime-crt-features-fixes-and-breaking-changes-in-visual-studio-14-ctp1/
Signed-off-by: Martin Storsjö <[email protected]>
---
mingw-w64-crt/Makefile.am | 2 ++
.../stdio/ucrt___local_stdio_printf_options.c | 15 +++++++++++++++
.../stdio/ucrt___local_stdio_scanf_options.c | 15 +++++++++++++++
mingw-w64-headers/crt/corecrt_stdio_config.h | 14 ++++++++++++--
4 files changed, 44 insertions(+), 2 deletions(-)
create mode 100644 mingw-w64-crt/stdio/ucrt___local_stdio_printf_options.c
create mode 100644 mingw-w64-crt/stdio/ucrt___local_stdio_scanf_options.c
diff --git a/mingw-w64-crt/Makefile.am b/mingw-w64-crt/Makefile.am
index f2f1e6f81..345eac0aa 100644
--- a/mingw-w64-crt/Makefile.am
+++ b/mingw-w64-crt/Makefile.am
@@ -401,6 +401,8 @@ src_ucrtbase=\
misc/_onexit.c \
misc/output_format.c \
misc/ucrt-access.c \
+ stdio/ucrt___local_stdio_printf_options.c \
+ stdio/ucrt___local_stdio_scanf_options.c \
stdio/ucrt_fprintf.c \
stdio/ucrt_fscanf.c \
stdio/ucrt_ms_fprintf.c \
diff --git a/mingw-w64-crt/stdio/ucrt___local_stdio_printf_options.c
b/mingw-w64-crt/stdio/ucrt___local_stdio_printf_options.c
new file mode 100644
index 000000000..986c4fd10
--- /dev/null
+++ b/mingw-w64-crt/stdio/ucrt___local_stdio_printf_options.c
@@ -0,0 +1,15 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the mingw-w64 runtime package.
+ * No warranty is given; refer to the file DISCLAIMER.PD within this package.
+ */
+
+#undef __MSVCRT_VERSION__
+#define _UCRT
+#include <corecrt_stdio_config.h>
+
+static unsigned __int64 options = _CRT_INTERNAL_PRINTF_LEGACY_WIDE_SPECIFIERS
| _CRT_INTERNAL_PRINTF_STANDARD_ROUNDING;
+
+unsigned __int64* __local_stdio_printf_options(void) {
+ return &options;
+}
diff --git a/mingw-w64-crt/stdio/ucrt___local_stdio_scanf_options.c
b/mingw-w64-crt/stdio/ucrt___local_stdio_scanf_options.c
new file mode 100644
index 000000000..2dbd32456
--- /dev/null
+++ b/mingw-w64-crt/stdio/ucrt___local_stdio_scanf_options.c
@@ -0,0 +1,15 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the mingw-w64 runtime package.
+ * No warranty is given; refer to the file DISCLAIMER.PD within this package.
+ */
+
+#undef __MSVCRT_VERSION__
+#define _UCRT
+#include <corecrt_stdio_config.h>
+
+static unsigned __int64 options = _CRT_INTERNAL_SCANF_LEGACY_WIDE_SPECIFIERS;
+
+unsigned __int64* __local_stdio_scanf_options(void) {
+ return &options;
+}
diff --git a/mingw-w64-headers/crt/corecrt_stdio_config.h
b/mingw-w64-headers/crt/corecrt_stdio_config.h
index 3028d92e1..7ac0e6e03 100644
--- a/mingw-w64-headers/crt/corecrt_stdio_config.h
+++ b/mingw-w64-headers/crt/corecrt_stdio_config.h
@@ -9,6 +9,13 @@
#include <corecrt.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+unsigned __int64* __local_stdio_printf_options(void);
+unsigned __int64* __local_stdio_scanf_options(void);
+
#define _CRT_INTERNAL_PRINTF_LEGACY_VSPRINTF_NULL_TERMINATION 0x0001ULL
#define _CRT_INTERNAL_PRINTF_STANDARD_SNPRINTF_BEHAVIOR 0x0002ULL
#define _CRT_INTERNAL_PRINTF_LEGACY_WIDE_SPECIFIERS 0x0004ULL
@@ -21,11 +28,14 @@
#define _CRT_INTERNAL_SCANF_LEGACY_MSVCRT_COMPATIBILITY 0x0004ULL
#ifndef _CRT_INTERNAL_LOCAL_PRINTF_OPTIONS
-#define _CRT_INTERNAL_LOCAL_PRINTF_OPTIONS
(_CRT_INTERNAL_PRINTF_LEGACY_WIDE_SPECIFIERS |
_CRT_INTERNAL_PRINTF_STANDARD_ROUNDING)
+#define _CRT_INTERNAL_LOCAL_PRINTF_OPTIONS (*__local_stdio_printf_options())
#endif
#ifndef _CRT_INTERNAL_LOCAL_SCANF_OPTIONS
-#define _CRT_INTERNAL_LOCAL_SCANF_OPTIONS
_CRT_INTERNAL_SCANF_LEGACY_WIDE_SPECIFIERS
+#define _CRT_INTERNAL_LOCAL_SCANF_OPTIONS (*__local_stdio_scanf_options())
#endif
+#ifdef __cplusplus
+}
+#endif
#endif /* _STDIO_CONFIG_DEFINED */
--
2.43.0
_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public