Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

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

The import declaration in C++20 makes exported symbols from a named module, module partition, or header unit visible within the current translation unit. Unlike the #include preprocessor directive, import does not perform textual inclusion; it loads pre-compiled module interface metadata, preventing macro leakage and isolating the state of the translation unit.

Syntax Variations

The import statement takes several forms depending on the target being imported:
// 1. Importing a named module
import module_name;
import core.network; // Modules can have dot-separated hierarchical names

// 2. Importing a module partition (only valid within the same module)
import :partition_name;

// 3. Importing a header unit (C++20 standard library approach)
import <iostream>;
import "my_header.h";

// 4. Re-exporting an imported module (transitive import)
export import module_name;

Placement and Scope Rules

In a modularized translation unit, import declarations are strictly governed by scoping and ordering rules. First, all import declarations must appear strictly at global namespace scope. They cannot be placed at block scope (inside functions), class scope, or inside named namespaces. Second, in a module unit, all imports—including header units—must appear in the module preamble. The preamble is the section immediately following the module declaration but preceding any other declarations.
module; // Starts the global module fragment (optional)

#include <cstdint> // Preprocessor directives go here

export module my_module; // Module declaration

// --- MODULE PREAMBLE BEGINS 
import <iostream>;       // Header unit import
import :internal_partition;
// --- MODULE PREAMBLE ENDS 

// Standard declarations must come AFTER all imports
void do_something(); 

// ERROR: Cannot import after declarations have started
// import another_module; 

namespace my_namespace {
    // ERROR: Imports cannot appear inside a named namespace
    // import <string>;
}

void func() {
    // ERROR: Imports cannot appear at block scope
    // import <vector>;
}

Types of Imports

1. Named Module Import

Imports a compiled module interface (often represented by .pcm, .ifc, or .bmi files depending on the compiler). Macros defined in the imported module are explicitly not visible to the importing translation unit.

2. Module Partition Import

A module can be split into partitions. A primary module interface or module implementation file can import its own partitions using the : prefix. Partitions cannot be imported by external modules directly.

3. Header Unit Import

A transitional mechanism that compiles a traditional header file into a synthesized module interface. Unlike named modules, importing a header unit does import macros defined within that header, making it a bridge between legacy preprocessor code and the module system.

Visibility vs. Reachability

When a module is imported, C++ enforces a strict distinction between visibility and reachability:
  • Visibility: Only entities explicitly marked with the export keyword in the imported module are visible to name lookup in the importing translation unit.
  • Reachability: Unexported entities may still be reachable. If an exported function returns an unexported class type, the importing translation unit cannot name the class directly, but the compiler can still reach its definition to allocate memory, invoke its member functions, or instantiate templates.

Transitive Imports (export import)

By default, imports are not transitive. If Module A imports Module B, and Module C imports Module A, Module C does not see Module B’s exports. To forward dependencies, a module must use export import. This makes the exported entities of the imported module visible to any translation unit that imports the current module.
export module facade_module;

// Any translation unit importing 'facade_module' 
// will also see the exports of 'sub_module_a'.
export import sub_module_a; 

// Internal dependency; not visible to importers of 'facade_module'.
import sub_module_b; 
Master C++ with Deep Grasping Methodology!Learn More