Global state in the CRT
Some functions in the Universal C Runtime (UCRT) use global state. For example, setlocale()
sets the locale for the entire program, which affects the digit separators, text code page, and so on.
The UCRT's global state isn't shared between applications and the OS. For example, if your application calls setlocale()
, it won't affect the locale for any OS components that uses the C run-time, or the other way around.
OS-specific versions of CRT functions
In the UCRT, functions that interact with global state have a "twin" function, prefixed with _o_
. For example:
setlocale()
affects global state specific to the app._o_setlocale()
affects global state shared by all OS components, but not apps.
The only difference between these "twin" functions is that when they read/write the global CRT state, the OS-specific versions (that is, the versions that start with _o_
) use the OS copy of global state instead of the app's copy of global state.
The OS-specific versions of these functions are in ucrt.osmode.lib
. For example, the OS-specific version of setlocale()
is _o_setlocale()
There are two ways to isolate your component's CRT state from an app's CRT state:
- Statically link your component by using compiler options
/MT
(release) or/MTd
(debug). For details, see /MD, /MT, /LD. Static linking can greatly increase binary size. - Starting in Windows versions beginning with Windows 10 version 2004, dynamically link to the CRT but call the OS-mode exports (the functions that begin with o). To call the OS-mode exports, statically link as before, but ignore the static UCRT by using linker option
/NODEFAULTLIB:libucrt.lib
(release) or/NODEFAULTLIB:libucrtd.lib
(debug). And adducrt.osmode.lib
to the linker input. See/NODEFAULTLIB
(Ignore Libraries) for details.
Note
In source code, write setlocale()
, not _o_setlocale()
. When you link against ucrt.osmode.lib
, the linker will automatically substitute the OS-specific version of the function. That is, setlocale()
will be substituted with _o_setlocale()
.
Linking against ucrt.osmode.lib
disables some UCRT calls that are only available in app mode. Attempting to call these functions will result in a link error.
Global state affected by app/OS separation
Global state affected by the separation of app and OS state includes:
- Locale data
- Signal handlers set by
signal
- Termination routines set by
terminate
errno
and_doserrno
- Random number generation state used by
rand
andsrand
- Functions that return a buffer that the user doesn't need to release:
strtok
,wcstok
,_mbstok
Tmpnam
,_wtmpnam
asctime
,_wasctime
gmtime
,_gmtime32
,_gmtime64
_fcvt
_ecvt
strerror
,_strerror
,_wcserror
,__wcserror
- The buffer used by
_putch
,_putwch
_set_invalid_parameter_handler
,_set_thread_local_invalid_parameter_handler
_set_new_handler
and_set_new_mode
fmode
- Time zone information