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
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
/MTd(debug). For details, see /MD, /MT, /LD. Static linking can greatly increase binary size.
- Starting 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:libucrtd.lib(debug). And add
ucrt.osmode.libto the linker input. See /NODEFAULTLIB (Ignore Libraries) for details.
In source code, write
_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
ucrt.osmode.lib disables some UCRT calls that are only available in app mode. Attempting to call these 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 and srand
- 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
- Time zone information