Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/MicrosoftDocs/cpp-docs/llms.txt

Use this file to discover all available pages before exploring further.

The Microsoft C Runtime Library (CRT) provides the foundational routines that power nearly every C and C++ program compiled with MSVC. From basic I/O and string manipulation to math, memory allocation, time functions, and process control, the CRT abstracts operating-system internals into a portable, well-defined API. Understanding which CRT variant your project links against is critical for both correctness and deployment — the wrong choice can cause DLL conflicts, state isolation bugs, or redistributable packaging errors.

What the CRT Provides

The CRT is organized into functional categories, each mapping to a well-known area of the C standard library or Windows-specific extensions:

I/O & File Handling

printf, scanf, fopen, fread, fwrite, fclose, fseek, ftell — complete ANSI C stream I/O plus Windows extensions.

String Manipulation

strcpy_s, strcat_s, strlen, strtok_s, sprintf_s, sscanf_s — safe and unsafe variants for byte and wide strings.

Memory Allocation

malloc, calloc, realloc, free, _aligned_malloc, memcpy_s, memmove_s — heap management and buffer operations.

Math & Floating-Point

sqrt, pow, sin, cos, floor, ceil, fabs, fmod — full C99 math library with floating-point support.

Time Management

time, clock, localtime_s, gmtime_s, mktime, difftime, strftime — POSIX-compatible time functions.

Process & Environment

exit, atexit, _exit, system, getenv, _putenv, abort — process lifecycle and environment variable access.

CRT Variants and Compiler Options

When you build with MSVC, the linker option you choose determines which CRT library your binary links against. This is one of the most important build decisions you will make.
OptionLibraryTypeCharacteristics
/MDmsvcrt.libucrtbase.dllDynamic (DLL)Shared CRT state across DLLs; requires Visual C++ Redistributable
/MTlibcmt.libStaticCRT compiled into your binary; no external DLL dependency
// Project Property Pages → C/C++ → Code Generation → Runtime Library
// /MD  → Multi-threaded DLL
// /MT  → Multi-threaded (static)

Static vs Dynamic Linking Trade-offs

Dynamic linking (/MD) means all DLLs and the main executable share a single CRT instance. This allows heap memory allocated in one module to be freed in another — a requirement if you pass std::string, std::vector, or raw malloc pointers across DLL boundaries. It also means Windows Update can service the CRT independently, improving security.
// With /MD: safe to pass std::string across DLL boundary
// (both sides share the same CRT heap)
__declspec(dllexport) void ProcessData(std::string& data);
Static linking (/MT) produces a self-contained binary with no dependency on redistributable DLLs. This is useful for small command-line utilities or plugins where you control the entire binary. However, every module (EXE + DLLs) gets its own CRT heap — passing heap-allocated pointers across module boundaries causes undefined behavior.
// With /MT: DANGEROUS to pass malloc'd memory across DLL boundary!
// Module A allocates with its CRT; Module B frees with a different CRT
All modules in a process must use the same CRT variant. Mixing /MD and /MT within a process is a common source of hard-to-diagnose crashes and assertion failures.

Universal CRT (UCRT) vs Legacy CRT

Starting with Visual Studio 2015, the CRT was split into two components:
1

Universal CRT (UCRT)

ucrtbase.dll — contains all standard C99 functions (stdio, math, string, etc.). The UCRT ships as part of Windows 10 and later, and is available on older Windows via the Windows SDK redistributable. It is now a stable, OS-versioned component.
libucrt.lib   → static UCRT (/MT)
ucrt.lib      → import library for ucrtbase.dll (/MD)
libucrtd.lib  → debug static UCRT (/MTd)
ucrtd.lib     → debug DLL UCRT (/MDd)
2

VC Runtime (vcruntime)

vcruntime140.dll — contains compiler-specific support: exception handling (__try/__except), C++ type information, security cookies, and certain intrinsics. This component is version-specific and ships with the Visual C++ Redistributable.
libvcruntime.lib    → static (/MT)
vcruntime.lib       → DLL import (/MD)
3

C++ Standard Library

msvcp140.dll — implements the C++ Standard Library (STL). Separate from the C runtime, this library provides containers, algorithms, streams, and concurrency primitives.

Legacy CRT (pre-VS 2015)

Before Visual Studio 2015, msvcr120.dll, msvcr110.dll, etc. bundled the C runtime and VC runtime together. These versions are version-specific and require matching redistributables. They are still supported but no longer receive new features.
Visual Studio 2013: msvcr120.dll
Visual Studio 2012: msvcr110.dll
Visual Studio 2010: msvcr100.dll

CRT Initialization and Global State

The UCRT maintains global state (locale, heap, stdio buffers) at the process level when using /MD. When using /MT, each statically linked module has its own isolated CRT state. This means strtok positions, file handles opened in one module, and locale settings are not shared across static CRT boundaries.

Subsections

Build docs developers (and LLMs) love