Macros Are Not Exported by import std (Russian Blue)
Macros and the Module Boundary showed that a module never exports macros, full stop. import std; is no exception to its own rule: it’s a standard-conforming C++ module, so it exports real C++ entities only. Several C headers <cerrno>, <csignal>, <cstdio> among them define their public surface partly or entirely as preprocessor macros, and import std; doesn’t fill that gap. This module needs errno and EINTR, both macros from <cerrno>, alongside everything import std; provides.
1 module;
2
3 #include <cerrno> // errno and EINTR are preprocessor macros -- import std
4 // does not export them. std::errc exists as the C++
5 // vocabulary for error conditions, but it's a distinct
6 // type, not a stand-in for the raw macro.
7
8 export module RussianBlue;
9
10 import std;
11
12 export auto meow() -> void {
13 errno = EINTR;
14 std::println("Русская голубая кошка говорит «Мяу». (errno={})", errno);
15 errno = 0;
16 }
The global module fragment (lines 1-6) still does exactly the job it always has — #include-ing a header for its preprocessor-level content — even in a file that also does import std; (line 10) a few lines later. There’s nothing unusual about mixing the two; a global module fragment #include and a module import are answering different questions: one supplies macros and other preprocessor-only content, the other supplies everything else.
![]() |
|
Building RussianBlue is otherwise identical to Importing the Standard Library — the same CMAKE_EXPERIMENTAL_CXX_IMPORT_STD project-wide gate, the same per-target CXX_MODULE_STD and CXX_EXTENSIONS properties, the same raw-script mechanics for both compilers.
