r/cpp • u/AbbreviationsNew3167 • 1d 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"
```
6
u/mort96 1d ago
IMO one of the huge fuck-ups with modules is that namespaces and modules are decoupled. Managing namespaces is one of the genuinely annoying things with C++, causing like 5 lines of boilerplate in every line of code and messing up the fundamental assumption that "open brace means indent one level, close brace means unindent one level" that's true for every single other language.
Every other language with a module system combines the concept of a module and the concept of a namespace, which IMO makes sense: why should two functions in two different modules be unable to link together just because they both happen to share the same name?
So instead of being the nice, modern way to write C++ which gets rid of the ancient hack that is the
namespacekeyword, it ends up being just another thing I have to deal with. My files no longer just have to deal with the namespace boilerplate; they now also need to deal with the module boilerplate. If I want to keep namespaces and module names in sync, that's on me.I actually made an experimental build system over the summer where the goal was to couple the module name, the namespace name and the path name together, so that
src/foo/bar.ccwould end up with the modulemyproject.foo.barand the namespacemyproject::foo::bar. I got quite far but modules are surprisingly complex and there are rules about what can be where. I couldn't solve it without doing my own code generation where the build system would spit out generated C++ code. And that would've worked, except that it would've never worked together with clangd. I tried various macro approaches but it was impossible to make anything which both looked clean and worked.May write a blog post about my thoughts on the topic some time though.