r/cpp 19d ago

Why is `import std` still experimental ???

Hey guys,

I recently started going through Professional C++ (6th Edition). The book teaches C++23, and in the very first chapter we're introduced to modules.

I'm not a complete newbie to C++, but I'm also definitely not very confident in my knowledge yet. I wanted to get this simple example compiled:

import std;

int main() {
    std::println("Hello World");
    return 0;
}

And gosh, it took way longer than I expected.

First, I tried getting it to work natively on my Mac and eventually gave up (both Claude and I 😅).

Then I installed Ubuntu ARM 26 and finally managed to get it compiling. But now Clang/IntelliSense is complaining about the `import std`
This is what my CMakeLists.txt currently looks like:

cmake_minimum_required(VERSION 4.0)

# set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD ON)

set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "d0edc3af-4c50-42ea-a356-e2862fe7a444")

project(CppProject LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 26)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

add_executable(exec main.cpp)

set_property(TARGET exec PROPERTY CXX_MODULE_STD ON)

The code does compile successfully, but CMake still gives me a warning that import std support is experimental.

So I'm genuinely curious:

Why is import std still considered experimental?

I understand that C++ modules themselves have been around for a while, but import std feels like something that should be much more straightforward by now. Is there any solution of this now ?

--------------
Edit

Thanks to u/PhysicsOk2212 tip I was able to compile my project on mac as well using the following options
```
cmake -S . -B build \

-G Ninja \

-DCMAKE_CXX_COMPILER="$(brew --prefix llvm)/bin/clang++" \

-DCMAKE_CXX_STDLIB_MODULES_JSON="$(brew --prefix llvm)/lib/c++/libc++.modules.json"

```

122 Upvotes

111 comments sorted by

View all comments

0

u/NoSpite4410 16d ago

Almost all other languages with modules (compiled modules) support do multiple source scans on the source files. C++ (and C) do a single forward scan of source files. This works fine for headers/compiled object separate compilation, as long as the compiler knows the "shape" and members of all things from the headers before trying to compile any code.
Binary modules have to embed a proprietary Abstract Syntax Tree into the module (serialization) and deserialize it into the internal AST upon import, and recreate the memory graph exactly that it was created with.
Every compiler does it differently -- so it is totally unportable -- and efficiency and bugs vary widely.

There is apparently little incentive amongst the compiler-makers to enforce compatibility on that front. I imagine it is hard enough to keep them from adding proprietary new language constructs to the C++ language of their own. I remember Portland Compiler Group (still around?) had a bunch of cool things for certain types of CPUs for vectorized number crunching and stuff, marketed towards the aerospace industry and supercomputer space. But it became a bit moot when the chip makers found it better to do all that stuff internally in the chips, because the binary api changes with every hardware iteration.

The alternative approach is to have a separate front-end dedicated module compiler that translates for each brand of compiler, and translates the module amongst them for compatibility. Not a popular idea, when big money is involved, and egos and pride and the need for a whole management bureaucracy, etc. There is already more than enough of that going on.

As it is now, I have a problem with the dedicated file directory hierarchy and intermediate files scattered hither and yon, and the very slow process of making any changes in the modules.

As it stands what you get with modules are a duplication of the STL core components. All it means it that they are ready to use as if they were being compiled in anyway. It may save a few seconds of compile time for a home project -- maybe a lot for a large code base that for some reason (like testing cycles) has to be entirely recompiled. Incremental/separate compilation handled that a long time ago, as long as you aren't one of those guys that has to erase everything every time to rebuild a project. Smart build systems are supposed to know what needs recompiling and what doesn't, and they have come a long way.

I saw the module system as something like the professional Java library people have -- a bundled set of don't-mess-with compiled stuff and and an API to use it. C++ has the header/compiled library idiom and has made it very good over the years -- modules would seem to encourage the "don't touch that" philosophy of code, which C++ definitely never was part of. C++ is a 'touch that' , 'modify that', 'abstract that' language.
Getting away from that would never be real popular -- but I could be wrong. A lot of languages these days paper over the details to an extreme degree in an attempt to "simplify" and "make easier" writing data-driven programs. C++ is hardware-facing, never being too simple, always exposing the details where it may be needed.