続・モジュール
2020-01-28
C++ MIX #7
Tetsuro Matsumura
目次
1. モジュールとモジュールユニット
2. モジュールユニットの依存関係
3. パーティション
4. フラグメント
5. ヘッダーユニット
6. パフォーマンス
7. 実装状況
1
モジュール
2
C++20では、ヘッダーファイルに代わる仕組みとしてモジュールが導入され、
プリプロセッサを用いずにプログラムを分割できる。
// datetime.h
#ifndef LIB_DATETIME_H
#define LIB_DATETIME_H
#include "core.h"
namespace lib {
…
}
#endif
// datetime.cpp
export module lib.datetime;
import lib.core;
export namespace lib {
…
}
// main.cpp
#include "datetime.h“
int main() {
…
}
// main.cpp
import lib.datetime;
int main() {
…
}
モジュールユニットの分類
3
モジュール宣言を含む翻訳単位(モジュールユニット)は、4つに分類できる
export module lib.datetime; module lib.datetime;
export module lib.datetime:date; module lib.datetime:dateimpl;
モジュール実装ユニット
ソースファイルに相当
モジュールインターフェースユニット
ヘッダーファイルに相当
パーティション: モジュールを分割するのに使う
export module lib.datetime;
export module lib.datetime:date;export module lib.datetime:date; module lib.datetime:dateimpl;
モジュールユニットの分類
4
モジュール名が同じなら同じモジュール(モジュールは複数の翻訳単位で構成できる)
パーティション名は翻訳単位間でユニーク
export module lib.datetime; module lib.datetime;
export module lib.datetime:date; module lib.datetime:dateimpl;
モジュール内の依存関係
5
export module lib.datetime;
プライマリーモジュールインターフェースユニット
module lib.datetime;
モジュール実装ユニット
暗黙的インポート
import lib.datetime;
モジュールユニット間のインポートの向きは決まっている(依存の循環は禁止)
モジュール lib.datetime
⚫ 外からインポートするのは「インターフェース」。
⚫ 「インターフェース」ではエクスポート宣言ができる。「実装」ではできない。
⚫ パーティションでないモジュール実装ユニットは、
プライマリーモジュールインターフェースユニットを暗黙的にインポートする
外部からのインポート
#includeの依存関係
6
lib/datetime.h
ヘッダーファイル
lib/datetime.cpp
ソースファイル
#include
#include
実は#includeが作る依存関係と同じ
モジュール lib/datetime
モジュール内の依存関係(パーティション)
7
export module lib.datetime;
プライマリーモジュールインターフェースユニット
module lib.datetime;
モジュール実装ユニット
export module lib.datetime:date;
モジュールインターフェース
パーティション
module lib.datetime:impl;
モジュール実装パーティション
暗黙的インポート
外部からのインポート
パーティションは同一モジュール内でインポートできるモジュール(依存の循環は禁止)
モジュール lib.datetime
インターフェースパーティションと実装パーティション
インターフェースパーティション
⚫ インターフェースを分割するためのもの。エクスポート宣言できる。
⚫ 必ず再エクスポートする必要がある = 外から間接的にインポートされる。
実装パーティション
⚫ エクスポート宣言できない。再エクスポートもできない。
⚫ モジュール内でプライベートに使う共通コードを置く。
module lib.datetime:impl;
export module lib.datetime:date;
パーティションはいつ使う?
9
ソースファイルが長いので分けたい場合や、プライベートな物を分けたい場合に適する。
モジュールパーティションの存在は外部からはわからないので、
単独でも使用できるなら、独立したモジュールにしたほうが良い。
export module lib.datetime;
export import :date;
export import :time;
export module lib.datetime:date;
export module lib.datetime:time;
export module lib.datetime;
export import lib.datetime.date;
export import lib.datetime.time;
export module lib.datetime.date;
export module lib.datetime.time;
パーティションで分割: 外からは使えない 別のモジュールに分割: 単独でも使える
※モジュール名にはドットが使えるが、特別な意味はない
フラグメント
10
ファイル(翻訳単位)を分けずにモジュールを分ける機能
⚫ グローバルモジュールフラグメント
グローバルモジュール(モジュールの外側)のコードを書ける。
⚫ プライベートモジュールフラグメント
プライベートなコードを書ける。(外から到達できない)
グローバルモジュールフラグメント
11
モジュール宣言の前にグローバルモジュールの実装を書ける。
ただし、プリプロセッサしか書けない。
モジュール内ではODRの例外がない。#includeするとほぼODR違反。
※ 同じトークン列ならODR違反にならないという例外
#includeを書く場合、グローバルモジュールフラグメントに書く。
module;
#include <iostream>
#include <vector>
export module foo;
#include "lib.h" //ODR違反!!
void f() { std::cout << "foo" << std::endl; }
グローバル
モジュール
モジュール内部
プライベートモジュールフラグメント
12
1ファイルでインターフェースと実装を分ける機能
※ これを使う場合、モジュールは1つの翻訳単位しか持てない
export module foo;
struct foo {
foo();
};
module :private;
foo::foo(){…}
モジュール
インターフェース
プライベート
モジュール
フラグメント
プライベートモジュールフラグメント内ではエクスポート宣言できない。
外部から到達可能にはならない。
→ いわゆる “detail名前空間”に最適
後方互換性のための機能
13
従来のヘッダーファイルによって提供されるライブラリのための機能がある。
⚫ グローバルモジュールフラグメント
モジュール本体への影響が少ないようにインクルードできる機能
⚫ ヘッダーユニット
ヘッダーファイルをモジュールとしてインポートできる機能
ヘッダーユニット
14
一部のヘッダーファイルをモジュールとしてインポートできる機能。
export module foo;
import <iostream>;
void f() { std::cout << "foo" << std::endl; }
⚫ 効果は#includeとほぼ同じ(マクロも取り込まれる)
⚫ 別の翻訳単位としてコンパイルされインポートされる
⚫ C++ライブラリヘッダーと処理系定義のヘッダーがインポートできる
※ <cmath>などのC互換ライブラリは不可
処理系によってはユーザーが指定できる
⚫ 処理系は#includeをimportに置換できる
モジュールでビルドは速くなるか
15
モジュールによってビルドが速くなると言われている
• #includeと違ってコードが展開されないので、解析が速くなる
一方、かえって遅くなるという主張もある
• モジュールの依存関係順にコンパイルする必要があるので、並列化しにくくなる
モジュールのベンチマーク P1441R1
16
モジュールなし
モジュールあり
並列数が少ない場合は、モジュールに分けると速くなる
モジュールのベンチマーク P1441R1
17
モジュールなし
モジュールあり
並列数が多い場合は依存が複雑だと遅くなる
(従来のビルドとは異なる特性)
実装状況
18
すべて実装している処理系はまだ存在しない。
⚫ モジュールインターフェース、モジュール実装までは動く。
(GCC/Clang/MSVC)
Wandboxでも実行可能: https://wandbox.org/permlink/lf6IvzvuFR8voprK
⚫ Visual Studio 2019 16.5でグローバルモジュールフラグメント、パーティション、
ヘッダーユニットが実装。ユーザー指定のヘッダーユニットも動く。
https://devblogs.microsoft.com/cppblog/c-modules-conformance-
improvements-with-msvc-in-visual-studio-2019-16-5/
19
まとめ
⚫ #includeに代わる仕組みとしてモジュールが導入された
⚫ プリプロセッサを用いずにプログラムを分割できる
⚫ ファイル構成はそれほど変わらない
ヘッダーファイル ≃ モジュールインターフェースユニット
ソースファイル ≃ モジュール実装ユニット
⚫ ヘッダーファイルから緩やかに移行できる (ヘッダーユニット)
⚫ モジュールで速くなるかは断言できない
⚫ 実装は進んできている
20
参考リンク
⚫ Working Draft, Standard for Programming Language C++ - 10. Modules
http://eel.is/c++draft/module
⚫ cpprefjp モジュール
https://cpprefjp.github.io/lang/cpp20/modules.html
⚫ [C++]モジュール理論 基礎編
https://onihusube.hatenablog.com/entry/2019/07/07/025446
⚫ [C++]モジュール理論 上級編(魔境編)
https://onihusube.hatenablog.com/entry/2019/07/17/183137

More Related Content

PDF
C++20 モジュールの概要 / Introduction to C++ modules (part 1)
PDF
ARM CPUにおけるSIMDを用いた高速計算入門
PPTX
Effective Modern C++ 勉強会 Item 22
PDF
オンラインゲームの仕組みと工夫
PDF
プログラムの処方箋~健康なコードと病んだコード
PPTX
ゲーム開発とMVC
PPTX
C#とILとネイティブと
PDF
分散学習のあれこれ~データパラレルからモデルパラレルまで~
C++20 モジュールの概要 / Introduction to C++ modules (part 1)
ARM CPUにおけるSIMDを用いた高速計算入門
Effective Modern C++ 勉強会 Item 22
オンラインゲームの仕組みと工夫
プログラムの処方箋~健康なコードと病んだコード
ゲーム開発とMVC
C#とILとネイティブと
分散学習のあれこれ~データパラレルからモデルパラレルまで~

What's hot (20)

PDF
組み込み関数(intrinsic)によるSIMD入門
PDF
Xbyakの紹介とその周辺
PPTX
【DL輪読会】GET3D: A Generative Model of High Quality 3D Textured Shapes Learned f...
PDF
C++ マルチスレッド 入門
PDF
マルチコアを用いた画像処理
PDF
モダン PHP テクニック 12 選 ―PsalmとPHP 8.1で今はこんなこともできる!―
PDF
インタフェース完全に理解した
PDF
デザイナのためのGit入門
PDF
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.
PPTX
[DL輪読会]Grokking: Generalization Beyond Overfitting on Small Algorithmic Datasets
PDF
Observableで非同期処理
PDF
Pythonによる黒魔術入門
PPTX
なぜなにリアルタイムレンダリング
PDF
【Unity道場スペシャル 2017札幌】乱数完全マスター
PDF
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
PDF
テストを書こう、Unity編
PPTX
競技プログラミングのためのC++入門
PDF
TLS, HTTP/2演習
PDF
Constexpr 中3女子テクニック
PDF
C# ゲームプログラミングはホントにメモリのことに無頓着でいいの?
組み込み関数(intrinsic)によるSIMD入門
Xbyakの紹介とその周辺
【DL輪読会】GET3D: A Generative Model of High Quality 3D Textured Shapes Learned f...
C++ マルチスレッド 入門
マルチコアを用いた画像処理
モダン PHP テクニック 12 選 ―PsalmとPHP 8.1で今はこんなこともできる!―
インタフェース完全に理解した
デザイナのためのGit入門
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.
[DL輪読会]Grokking: Generalization Beyond Overfitting on Small Algorithmic Datasets
Observableで非同期処理
Pythonによる黒魔術入門
なぜなにリアルタイムレンダリング
【Unity道場スペシャル 2017札幌】乱数完全マスター
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
テストを書こう、Unity編
競技プログラミングのためのC++入門
TLS, HTTP/2演習
Constexpr 中3女子テクニック
C# ゲームプログラミングはホントにメモリのことに無頓着でいいの?
Ad

Similar to 続・モジュール / Introduction to C++ modules (part 2) (20)

PDF
Code ignitertalk 01
PPTX
2015 0227 OSC-Spring Tokyo NETMF
PDF
The Twelve-Factor (A|M)pp with C#
PDF
Code igniterでテスト駆動開発 資料作成中
PPTX
今こそ知りたいSpring Web(Spring Fest 2020講演資料)
PDF
osakapy 2014.05 LT
PDF
バージョン管理システムチュートリアル
PDF
【de:code 2020】 リモートワークの端末を安全に使ってもらおう どこがパワフル Microsoft Endpoint Manager の Wi...
PDF
はじめてのCodeIgniter
PDF
Apache Airflow 概要(Airflowの基礎を学ぶハンズオンワークショップ 発表資料)
PDF
.NET Core時代のCI/CD
PDF
Clang Modules
PDF
Rtミドルウェア講習会 第2部資料
PDF
Tekton 入門
PDF
Prometheus超基礎公開用.pdf
PDF
Javaコードが速く実⾏される秘密 - JITコンパイラ⼊⾨(JJUG CCC 2020 Fall講演資料)
PDF
環境構築自動化ツールのご紹介
PPTX
PDF
FPGAアクセラレータの作り方 (IBM POWER+CAPI編)
PDF
.NETラボ 勉強会 2021年1月 「C#で機械学習」
Code ignitertalk 01
2015 0227 OSC-Spring Tokyo NETMF
The Twelve-Factor (A|M)pp with C#
Code igniterでテスト駆動開発 資料作成中
今こそ知りたいSpring Web(Spring Fest 2020講演資料)
osakapy 2014.05 LT
バージョン管理システムチュートリアル
【de:code 2020】 リモートワークの端末を安全に使ってもらおう どこがパワフル Microsoft Endpoint Manager の Wi...
はじめてのCodeIgniter
Apache Airflow 概要(Airflowの基礎を学ぶハンズオンワークショップ 発表資料)
.NET Core時代のCI/CD
Clang Modules
Rtミドルウェア講習会 第2部資料
Tekton 入門
Prometheus超基礎公開用.pdf
Javaコードが速く実⾏される秘密 - JITコンパイラ⼊⾨(JJUG CCC 2020 Fall講演資料)
環境構築自動化ツールのご紹介
FPGAアクセラレータの作り方 (IBM POWER+CAPI編)
.NETラボ 勉強会 2021年1月 「C#で機械学習」
Ad

続・モジュール / Introduction to C++ modules (part 2)