C++20 Modules - A complete guide

In Software Development

C++20 Modules - A complete guide - read the full article about C++ 2021, Software Development and from Šimon Tóth on Qualified.One
Šimon Tóth
Youtube Blogger

hello fellow c plus plus enthusiasts c plus plus 20 modules are slowly gaining support from compilers and build systems so this is the perfect time to learn about modules and benefit from the massive compilation speedups first a quick refresher on how c space headers are processed i will use this simple hello world program to demonstrate the preprocessor which runs before the actual compilation processes each header and then textually inserts it in the location of the original include because this process is recursive we often end up with massive text files slowing down our compilation for example in our hello world program we end up with almost 2 megabytes of text now consider that this happens for every implementation file in your project various vendors have recognized this problem and offer a non-standard feature using pre-compiled headers where a common set of headers is processed once and then included everywhere modules try to solve the same problem but in a standard way so lets have a look at the hello world in the world of modules the result is now only 200 bytes and looking at the time to compile we see a very similar story now of course we are cheating here a bit the module version is saving time by not processing the iostream header at all but on the other hand that is kind of the point with gcc we need to compile the header explicitly but we can use this opportunity to look at the overhead of modules overall this is approximately twice slower than just including the header the good news is that most of the time is spent compiling the header into a pre-compiled module which will only happen once importing standard headers as modules already gives us a solid bin in terms of compilation performance but let us get into the exciting part which is writing our own modules each module can consist of multiple files designated module units with one file exporting the module and serving as the module interface the module interface is also where we specify which symbols to export and therefore make visible modules are orthogonal to namespaces so nothing prevents you from exporting a symbol into the global namespace like the function plus here or export the custom namespace like the function minus here symbols note marked with export will not be visible outside of this module modules are imported by their name gcc will automatically emit a pre-compiled module when necessary so compiling this example is reasonably straightforward unfortunately the current version of clang collects functionality here the clank plus plus interface does not expose the required flags to build the pre-compiled module so we must pass the emit module interface flag through to the clank compiler after that things again work as expected if desired module can be split across multiple module units however only one file can serve as the interface and export the module and only the interface file will contribute to the pre-compiled module in such use case naturally this has implications for compile-time constructs alternatively modules can also be split into partitions partitions of a module are only accessible to the main module and must be a single unit they can either be internal by not serving as a module interface in which case the symbols of a partition are only available to the main module and such a partition cannot be exported or they can be a module interface with their own exports in which case they must be re-exported by the main module i already mentioned that only some files contribute to the pre-compiled modules the main implication this is for exporting compile-time constructs such as templates these need to be placed in files that do contribute to the pre-compiled modules which are module interface files and any module partition files however when you split a module across multiple units all your compile time constructs must be placed in the module interface file this might sound familiar since it mirrors the behavior of a single header with multiple implementation files attached to it so far i have not mentioned anything about macros macros still work however the big change from headers is that modules are not affected by macros at the import side if you still need this behavior for example for feature macros or x macros you can still use these in a special section of a module called the global module fragment that is it for the hard info about modules but i would like to share some stylistic recommendations while you can have modules exporting symbols into any namespace please dont do that fortunately module names can contain the dot symbol which does not have any semantic meaning so we can match up the module name with the namespace name by using the dot as a separator secondly because only some files contribute to the pre-compiled modules i recommend avoiding this confusion in your project each module should only consist of a single file which serves as the module interface and if splitting a module into multiple files improves readability use module partitions instead of simply adding more units and with that advice we are at the end of the video thank you for watching and see you in the next one you

Šimon Tóth: C++20 Modules - A complete guide - Software Development