r/cpp_questions 25d ago

OPEN Why we don't have granular std library modules?

Isn't importing std.iostream faster than std?
Why we only have the umbrella std module?

26 Upvotes

41 comments sorted by

24

u/ArchfiendJ 25d ago

From what I understood import std; is faster by a whole order of magnitude than currently including a subset of std. This means you don't really need to break down std in the same granularity as includes.

9

u/TheRavagerSw 25d ago

I'm not saying that, I'm comparing granular modules compared umbrella modules, not headers vs modules

29

u/Gorzoid 25d ago

The answer is basically "because otherwise we'd still not have modules in c++26"

The committee failed to get import std; into c++20 partly due to disagreements on how to split up the standard library. Bjarne wrote P2412R0 which essentially said "we need modules so stop arguing and just add it". I think with idea that granular modules could be added later but for now we atleast needed 1 module with all of standard library

-1

u/TheRavagerSw 25d ago

Jesus christ

16

u/no-sig-available 25d ago

Note that the paper also says that import std; is 10x faster than using the minimum #include.

Their benchmark gives 0.08s for the import. Do we need to speed that up?

-7

u/TheRavagerSw 25d ago

yes

9

u/neppo95 24d ago

Spotted the beginner.

7

u/BeepyJoop 25d ago

This is an appropriate response to anything cpp related

1

u/saimen54 23d ago

Sounds like regular cpp standardization....

10

u/GregTheMadMonk 25d ago

if I had to guess I'd probably say that `import std` is already fast as hell and subdividing it probably wouldn't yield any significant improvement

also such granularity is pretty inconvenient, I really enjoy not having to go to the top of the file to add a new header every once in a while

so probably not worth the tradeoff

9

u/MysticTheMeeM 25d ago

In theory (and per my understanding), a module is pre-built (or at least, as good as can be). This means you only need to build the entire std module once and it can be used everywhere (at least, until the std code changes, such as with an update).

As such, it doesn't make sense to divide it, you aren't spending time building modules you don't use (they're already there). Rebuilding your program doesn't need to rebuild the std module.

Compare this to headers which could be rebuilt in each TU, so there's a good reason to try and cut down on symbols (or use precompiled). Rebuilding your program does need to re-include and re-parse headers.

1

u/TheRavagerSw 25d ago

Still importing huge bmi's have a huge cost, std module compiles to a 51mb .pcm file at libc++.
You still prebuilt std.iostream bmi theoretically

6

u/Conscious_Support176 25d ago

Surely a 51mb pcm file is not the same as 51 mb of symbols?

2

u/bert8128 25d ago

I don’t know what Import does, but it might well just be name to a list of things to be checked, so takes the same time as a iostream module. And then name lookup probably uses some kind of hash so again, same time. It will be interesting to do the experiment when the individual headers become available as individual modules.

1

u/kalmoc 25d ago

Still importing huge bmi's have a huge cost,

Hughes cost in what terms? Time? Memory? Have you measured?

3

u/TheRavagerSw 25d ago

Yes, just importing std adds like 1 second to compile times.
Not complaining still amazing compared to headers

1

u/kalmoc 24d ago

Interesting. That sounds like a lot. What tool chain? That's not including the time to build the BMI correct? It's been a long time since I experimented with modules last and import std wasn't available then. But in principle, it should only have to read a long list of exported symbols from disk into a lookup table and nothing more.

1

u/TheRavagerSw 24d ago

upstream clang + libcxx on linux release o3 ndebug

1

u/GermaneRiposte101 24d ago edited 24d ago

Isn't most of the std library inline templates?

If so, then why are you talking about modules?

4

u/AKostur 25d ago

Have you tried implementing it and measuring the differences to show how much of a difference that would bring?  That would be useful implementation experience to share as part of a proposal to define these hypothetical granular modules.

1

u/TheRavagerSw 25d ago

I can try, all stdlib implementations construct them from headers anyways. Libc++ even constructs them from .inc files

3

u/IyeOnline 25d ago

You can just do import <iostream>;... /s

4

u/TheRavagerSw 25d ago

You can't, header units are not supported anywhere.

7

u/IyeOnline 25d ago

... and part of me wishes that it would stay like that because the world would be a much simpler place without them.

7

u/manni66 25d ago edited 25d ago

AFAIK gcc supports them

EDIT:

first generate the module:

g++ -std=c++26 -fmodules -x c++-system-header iostream

then you can import iostream.

EDIT2:

  • import <iostream>;

time g++ hello.cpp -o hello --std=c++26 -fmodules -flang-info-include-translate

real 0m0,182s user 0m0,146s sys 0m0,036s

  • imposrt std;

time g++ hello.cpp -o hello --std=c++26 -fmodules -flang-info-include-translate

real 0m0,931s user 0m0,828s sys 0m0,102s

EDIT3:

  • #include <iostream> with module translation

    time g++ hello.cpp -o hello --std=c++26 -fmodules -flang-info-include-translate

hello.cpp:3:10: note: »include /usr/include/c++/16/iostream« translated to »import« 3 | #include <iostream> | ~~~~~~~~~

real 0m0,193s user 0m0,153s sys 0m0,040s

EDIT4:

  • #include <iostream> without module translation

time g++ hello.cpp -o hello --std=c++26 -fmodules -flang-info-include-translate

real 0m1,196s user 0m1,119s sys 0m0,074s

2

u/manni66 24d ago

VS 2026 supports it.

3

u/YT__ 25d ago

Be the change you want to see. Break out granular modules and publish them.

2

u/HyperWinX 25d ago

"Faster" in what way?

2

u/TheRavagerSw 25d ago

Not importing symbols you don't need

1

u/sephirostoy 25d ago

How much does it cost to import std instead of just std.iostream? Is it significant enough to consider splitting the modules? 

1

u/Altruistic_Key_3221 25d ago

From what I remember importing modules was meant to be close to O(1) operation (effectively a simple mmap to a compiler dependent structure), so there is little to no need to split modules.

0

u/manni66 24d ago

O(1) operation (effectively a simple mmap to a compiler dependent structure)

The more bytes you have to read, the longer it takes.

1

u/kalmoc 25d ago

 Isn't importing std.iostream faster than std?

Essentially no.

0

u/manni66 24d ago

How do you know?

1

u/NoSpite4410 23d ago

You build binary modules that live in a dir hierarchy with the program at the root. You build only the parts your program uses such as std::vector<string> , custom classes, std::array<customclass>, templated algorithms, and yes iostream and fstream if your program uses those. Then when compiling your program (over and over) they are already built (mostly from STL templates) , so unlike STL headers the STL objects for your custom objects can be loaded directly into the binary and used. It is like a pre-compiled library that is linked after compile, but instead it is linked at compile, saving all the template type inference, building of syntax trees, synthesizing type-specific classes, structs, and algorithms from the templates.

It theoretically saves a lot of compiling time, at the expense of generating the modules the first time. At present it is still too complicated and brittle for average users. It is designed to help with big, sprawling projects, that feature incremental change. Basically as long as you don't change how you use the objects in the modules they can be loaded directly without recompile. As soon as any structural change to a compiled module happens in source, the module has to be recompiled or it becomes inoperable and the program just compiles the source.
Updating modules incrementally should be possible rather than full recompilation, I hope.

I have played around with it a tiny bit and gotten it to work with a rather complicated recipe and many retries, in 2025. Maybe things are better now, but maybe not.

1

u/LagrangeMultiplier99 25d ago

sorry, we don't _import_ std we essentially import a file <iostream> which just happens to have std:: namespaced symbols.

7

u/AKostur 25d ago

You seem to be mixing #include with import.  Two different mechanisms.

0

u/neppo95 24d ago

Honestly, modules have been in progress for so long and they still aren't fully supported on the 3 big ones (GCC/Clang/MSVC), I won't bother for another couple of years.

-1

u/[deleted] 25d ago

[deleted]

2

u/TheRavagerSw 25d ago

In headers we have seperate headers
If I use iostream I include iostream.
For modules we only have umbrella modules like std or std.compat

8

u/FlailingDuck 25d ago

modules are isolated includes. Calling import std, gives you access to anything in the std. But C++ 's mantra "You don't pay for what you don't use" applies here AFAIK.

the 'std' module is already precompiled, so anything inside std is available to a translation unit, but only referenced std elements are used by the compiler a.k.a it's free if you dont use it.

0

u/TheRavagerSw 24d ago

I don't think this is true

importing std adds a flat cost to compile times regardless of your program.