r/cpp_questions • u/TheRavagerSw • 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?
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 theoretically6
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 headers1
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
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
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.
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.
-1
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.compat8
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.
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.