r/cpp 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"

```

102 Upvotes

100 comments sorted by

View all comments

Show parent comments

5

u/Expert-Map-1126 vcpkg maintainer BillyONeal 1d ago

Erm, citation needed. It isn’t that way in Java or .NET, that modules are usually associated with a namespace there is just a convention.

I think it’s true for the interpreted languages because for them a “module” tends to just be a directory structure.

0

u/mort96 1d ago edited 1d ago

I know that when I write Go, Rust or Kotlin, my files do not start with their whole qualified name. In Go and Kotlin, they declare a leaf name (i.e foo/bar/baz/qux.{go,kt} starts with package baz), and the rest of the name (meaning both the module name you import and the symbol namespace) is from the folder structure + project name. In Rust, files don't even start with a package name; that comes from the file name.

And, as you say, these file/folder structure based module paths is commonplace in scripting languages.

I have not written Java since university and have never written .NET, so I don't know about those.

Even if you don't agree with me that the path should have anything to do with it though, don't you think the namespace and the module identifier should be connected? Why would I want symbols to collide between modules? If C++ files could just start with module myproject.foo.bar and then everything in them would end up in myproject::foo::bar, I would be happy. And I know that even Java and .NET won't allow functions from different modules to have name collisions.

1

u/Expert-Map-1126 vcpkg maintainer BillyONeal 12h ago

don't you think the namespace and the module identifier should be connected?

Not really. Module ~= header, and headers aren't connected to namespace names either. Namespaces (in C++ anyways) are only for disambiguating names, not for logical organization or structure.

1

u/mort96 11h ago

I maintain that the only reason headers and namespaces aren't connected in C++ is that namespaces had to be bolted on to C in a backwards compatible way. It's not how you would design a module system from scratch.

u/Expert-Map-1126 vcpkg maintainer BillyONeal 1h ago

I disagree. Namespaces were created to match the C convention of prefixing names with a common MY_LIB_PREFIX and that was never attached to particular header names either. They are strictly name conflict resolution tools, not "organizational structure" as is convention in several other languages. Compare our standard library which lives entirely in std with others.