trainings/AdvancedCppV2/Presentation/moder_cpp_cpp20_modules.md

3.3 KiB

Modules

Legacy includes system form C language finally was replaced in C++20 by modules. include is actually 50 years old!

New keywords:

  • Export
  • Import

Less code in binary

#include <iostream>

int main() {
    std::cout << "Hello World!\n";    
}
g++ -std=c++2b -E main.cpp | wc -c
929065
import <iostream>;

int main() {
    std::cout << "Hello Modular World!\n";
}
g++ -std=c++2b -fmodules-ts main.cpp | wc -c   
239
___

Export

Modules provide better encapsulation because you can export only those methods, which you mark as exported. The rest of the functions stay hidden outside the file.

// calculator.cc
export module Calculator;

export auto add(auto x, auto y) {
    return x + y;
}

export auto substract(auto x, auto y) {
    return x - y;
}

export namespace Advanced {
    auto factorial(auto x) {
        decltype(x) res = 1;
        for (int i = 2 ; i <= x ; ++i) {
            res *= i
        }

        return res;
    }
}

void this_function_will_not_be_exported() {}

// main.cc
import <iostream>;
import Calculator;

int main() {
    std::cout << "10 + 20 = " << add(10, 20) << '\n';
    std::cout << "40 - 60 = " << substract(40, 60) << '\n';
    std::cout << "5! = " << Advanced::factorial(5) << '\n';
    // this_function_will_not_be_exported -> compile error
}

spread modules across multiple files

Only one file can be interface and export module. Other files can write implementations.

// interface.cc
export module calculator

export {
    auto add(auto x, auto y);
    auto substract(auto x, auto y);
}

// add.cc
module calculator

auto add(auto x, auto y) {
    return x + y;
}

// substract.cc
module calculator

auto substract(auto x, auto y) {
    return x - y;
}

// main.cc
import <iostream>;
import calculator;

int main() {
    std::cout << "10 + 20 = " << add(10, 20) << '\n';
    std::cout << "40 - 60 = " << substract(40, 60) << '\n';
}

Compiler and Cmake supoort

Unfortunately when we want to build binary with modules using g++ or clang even when we have the newest version (on 17.05.2022 there is g++ 13 and clang 15) we still have partial support for modules. It will takes a few years before we will start using this in customer projects. Currently, even CMake(3.23.1) Didn't fully support modules: (https://gitlab.kitware.com/cmake/cmake/-/issues/18355).