Skip to content

Repo sync for protected CLA branch #4326

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Dec 5, 2022
Merged
43 changes: 43 additions & 0 deletions docs/build/compare-inclusion-methods.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
description: "Learn about the different ways to include library headers in C++: header files vs modules vs header units vs precompiled headers."
title: "Compare header units, modules, and precompiled headers"
ms.date: 11/30/2022
f1_keywords: ["#include", "header file", "header unit", "module", "named module", "PCH", "precompiled header file", "IFC"]
helpviewer_keywords: ["headers, C++ library", "libraries, Standard C++", "C++ Standard Library, headers", "STL", "Standard template library, headers", "precompiled header files, creating", "PCH files, creating", "import", "header unit", "ifc", "modules [C++]", "named modules [C++]", "import standard library (STL) using named modules"]
---
# Compare header units, modules, and precompiled headers

Historically, you'd include the standard library with a directive like `#include <vector>`. However, it's expensive to include header files because they're reprocessed by every source file that includes them.

Precompiled headers (PCH) were introduced to speed compilation by translating them once and reusing the result. But precompiled headers can be difficult to maintain.

In C++20, modules were introduced as a significant improvement on header files and precompiled headers.

Header units were introduced in C++20 as a way to temporarily bridge the gap between header files and modules. They provide some of the speed and robustness benefits of modules, while you migrate your code to use modules.

Then, the C++23 standard library introduced support for importing the standard library as named modules. This is the fastest and most robust way to consume the standard library.

To help you sort out the different options, this article compares the traditional `#include` method against precompiled headers, header units, and importing named modules.

The following table is arranged by compiler processing speed and robustness, with `#include` being the slowest and least robust, and `import` being the fastest and most robust.

| Method | Summary |
|---|---|
| `#include` | One disadvantage is that they expose macros and internal implementation. Internal implementation is often exposed as functions and types that start with an underscore. That's a convention to indicate that something is part of the internal implementation and shouldn't be used.<br/><br/>Header files are fragile because the order of #includes can modify behavior or break code and are affected by macro definitions.<br/><br/>Header files slow compilation. Particularly when multiple files include the same file because then the header file is reprocessed multiple times. |
| [Precompiled header](../build/creating-precompiled-header-files.md) | A precompiled header (PCH) improves compile time by creating a compiler memory snapshot of a set of header files. This is an improvement on repeatedly rebuilding header files.<br/><br/>PCH files have restrictions that make them difficult to maintain.<br/><br/>PCH files are faster than `#include` but slower than `import`.|
| [Header units](../build/walkthrough-header-units.md) | This is a new feature in C++20 that allows you to import 'well-behaved' header files as modules.<br/><br/>Header units are faster than `#include`, and are easier to maintain, significantly smaller, and also faster than pre-compiled header files (PCH).<br/><br/>Header units are an 'in-between' step meant to help transition to named modules in cases where you rely on macros defined in header files, since named modules don't expose macros.<br/><br/>Header units are slower than importing a named module.<br/><br/>Header units aren't affected by macro defines unless they're specified on the command line when the header unit is built--making them more robust than header files.<br/><br/>Header units expose the macros and internal implementation defined in them just as header file do, which named modules don't.<br/><br/>As a rough approximation of file size, a 250-megabyte PCH file might be represented by an 80-megabyte header unit file. |
| [Modules](../cpp/modules-cpp.md) | This is the fastest and most robust way to import functionality.<br/><br/>Support for importing modules was introduced in C++20. The C++23 standard library introduces the two named modules described in this topic.<br/><br/>When you import `std`, you get the standard names such as `std::vector`, `std::cout`, but no extensions, no internal helpers such as `_Sort_unchecked`, and no macros.<br/><br/>The order of imports doesn't matter because there are no macro or other side-effects.<br/><br/>As a rough approximation of file size, a 250-megabyte PCH file might be represented by an 80-megabyte header unit file, which might be represented by a 25-megabyte module.<br/><br/>Named modules are faster because when a named module is compiled into an `.ifc` file and an `.obj` file, the compiler emits a structured representation of the source code that can be loaded quickly when the module is imported. The compiler can do some work (like name resolution) before emitting the `.ifc` file because of how named modules are order-independent and macro-independent--so this work doesn't have to be done when the module is imported. In contrast, when a header file is consumed with `#include`, its contents must be preprocessed and compiled again and again in every translation unit. <br/><br/>Precompiled headers, which are compiler memory snapshots, can mitigate those costs, but not as well as named modules. |

If you can use C++20 features and the C++23 standard library in your app, use named modules.

If you can use C++20 features but want to transition over time to modules, use header units in the interim.

If you can't use C++20 features, use `#include` and consider precompiled headers.

## See also

[Precompiled header files](creating-precompiled-header-files.md)\
[Overview of modules in C++](../cpp/modules-cpp.md)\
[Tutorial: Import the C++ standard library using modules](../cpp/tutorial-import-stl-named-module.md)\
[Walkthrough: Import STL libraries as header units](walkthrough-import-stl-header-units.md#approach1)\
[Walkthrough: Build and import header units in your Visual C++ projects](walkthrough-header-units.md)
8 changes: 6 additions & 2 deletions docs/build/creating-precompiled-header-files.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ description: "Learn more about: Precompiled header files"
title: "Precompiled Header Files"
ms.date: 06/29/2022
helpviewer_keywords: ["precompiled header files, creating", "PCH files, creating", "cl.exe compiler, precompiling code", ".pch files, creating"]
ms.assetid: e2cdb404-a517-4189-9771-c869c660cb1b
---
# Precompiled header files

Expand All @@ -21,7 +20,7 @@ Precompiled code is useful during the development cycle to reduce compilation ti

- You always use a large body of code that changes infrequently.

- Your program comprises multiple modules, all of which use a standard set of include files and the same compilation options. In this case, all include files can be precompiled into one precompiled header.
- Your program comprises multiple modules, all of which use a standard set of include files and the same compilation options. In this case, all include files can be precompiled into one precompiled header. For more information about newer ways to handle include files, see [Compare header units, modules, and precompiled headers](compare-inclusion-methods.md).

The first compilation (the one that creates the precompiled header file) takes a bit longer than subsequent compilations. Subsequent compilations can proceed more quickly by including the precompiled code.

Expand Down Expand Up @@ -341,5 +340,10 @@ int main( void )

## See also

[Compare header units, modules, and precompiled headers](compare-inclusion-methods.md)\
[C/C++ building reference](reference/c-cpp-building-reference.md)\
[MSVC compiler options](reference/compiler-options.md)
[Overview of modules in C++](../cpp/modules-cpp.md)\
[Tutorial: Import the C++ standard library using modules](../cpp/tutorial-import-stl-named-module.md)\
[Walkthrough: Build and import header units in your Visual C++ projects](walkthrough-header-units.md)\
[Walkthrough: Import STL libraries as header units](walkthrough-import-stl-header-units.md#approach1)
4 changes: 3 additions & 1 deletion docs/build/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ items:
href: ../build/cmake-predefined-configuration-reference.md
- name: "C++ Build Insights"
href: ../build-insights/get-started-with-cpp-build-insights.md
- name: "Build and import header units"
- name: "Compare header units, modules, and precompiled headers"
href: ../build/compare-inclusion-methods.md
- name: "Header units"
expanded: false
items:
- name: "Walkthrough: Build and import header units in Visual C++ projects"
Expand Down
2 changes: 2 additions & 0 deletions docs/build/walkthrough-header-units.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ This article is about building and importing header units with Visual Studio 202

Header units are the recommended alternative to [precompiled header files](creating-precompiled-header-files.md) (PCH). Header units are easier to set up and use, are significantly smaller on disk, provide similar performance benefits, and are more flexible than a [shared PCH](https://devblogs.microsoft.com/cppblog/shared-pch-usage-sample-in-visual-studio).

To contrast header units with other ways to include functionality in your programs, see [Compare header units, modules, and precompiled headers](compare-inclusion-methods.md).
## Prerequisites

To use header units, you need Visual Studio 2019 16.10 or later.
Expand Down Expand Up @@ -156,6 +157,7 @@ Enabling the new preprocessor affects the processing of variadic macros. For mor
[`/exportHeader`](./reference/module-exportheader.md)\
[`/headerUnit`](./reference/headerunit.md)\
[`header-units.json`](./reference/header-unit-json-reference.md)\
[Compare header units, modules, and precompiled headers](compare-inclusion-methods.md)\
[Overview of modules in C++](../cpp/modules-cpp.md)\
[Tutorial: Import the C++ standard library using modules](../cpp/tutorial-import-stl-named-module.md)\
[Walkthrough: Import STL libraries as header units](walkthrough-import-stl-header-units.md#approach1)
5 changes: 3 additions & 2 deletions docs/build/walkthrough-import-stl-header-units.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ This walkthrough shows how to import C++ Standard Template Library (STL) librari

Importing an STL header as a header unit is simpler than using [precompiled header files](creating-precompiled-header-files.md). Header units are easier to set up and use, are substantially smaller on disk, provide similar performance benefits, and are more flexible than a [shared PCH](https://devblogs.microsoft.com/cppblog/shared-pch-usage-sample-in-visual-studio).

For more detailed information about what header units are and the benefits they provide, see [What is a header unit?](walkthrough-header-units.md#what-is-a-header-unit)
For more detailed information about what header units are and the benefits they provide, see [What is a header unit?](walkthrough-header-units.md#what-is-a-header-unit). To contrast header units with other ways to import the standard library, see [Compare header units, modules, and precompiled headers](compare-inclusion-methods.md).

## Prerequisites

Expand Down Expand Up @@ -219,6 +219,7 @@ The main consideration for whether to use this approach is the balance between c

## See also

[Compare header units, modules, and precompiled headers](compare-inclusion-methods.md)\
[Tutorial: Import the C++ standard library using modules](../cpp/tutorial-import-stl-named-module.md)\
[Walkthrough: Build and import header units in your Visual C++ projects](walkthrough-header-units.md)\
[`/translateInclude`](./reference/translateinclude.md)
[`/translateInclude`](./reference/translateinclude.md)
5 changes: 4 additions & 1 deletion docs/cpp/modules-cpp.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ C++20 introduces *modules*, a modern solution that turns C++ libraries and progr

You can use modules side by side with header files. A C++ source file can `import` modules and also `#include` header files. In some cases, you can import a header file as a module rather than include it textually by using `#include` in the preprocessor. We recommend you use modules in new projects rather than header files as much as possible. For larger existing projects under active development, experiment with converting legacy headers to modules. Base your adoption on whether you get a meaningful reduction in compilation times.

To contrast modules with other ways to import the standard library, see [Compare header units, modules, and precompiled headers](../build/compare-inclusion-methods.md).

## Enable modules in the Microsoft C++ compiler

As of Visual Studio 2022 version 17.1, C++20 standard modules are fully implemented in the Microsoft C++ compiler.
Expand Down Expand Up @@ -200,4 +202,5 @@ import "myheader.h";
## See also

[`module`, `import`, `export`](import-export-module.md)\
[Named modules tutorial](tutorial-named-modules-cpp.md)
[Named modules tutorial](tutorial-named-modules-cpp.md)\
[Compare header units, modules, and precompiled headers](../build/compare-inclusion-methods.md)
Loading