Visual C++ 2015 Update 1でC++にmoduleが試験的に実装された
要約
12月1日のUpdate1でVisual C++にmoduleが試験的に実装されました channel9.msdn.com
このmoduleの文法はおおよそ
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4214.pdf
と近いものになっています。
moduleとは
javaのpackage/importや、C#のnamesoace/usingのような、他の高級言語ではポピュラーな機能です。関連するコンポーネント群を公開範囲を調整して外部へ公開できる機能といったところでしょうか。これにより、ライブラリごとの名前衝突を防げたり実装を遮蔽して疎結合にできる恩恵があります。
2015年時点のC++にはモジュール機能はありません。もっと原始的な、Cの時代から存在するヘッダをincludeするコピペ機能で誤魔化してきました。この方法ではincludeするヘッダの順序によって振る舞いが変わる恐れが存在したり、コンパイル時間の増大の原因となっていました。そういったことに対処する意味でも、module機能は必須といえます。
使い方
本当に試験的な実装で、まだVisual Studio上で快適に利用できる、というレベルには達してません。moduleの詳しい文法は
本の虫: 2014-10-pre-UrbanaのC++標準化委員会文書のレビュー: N4210-N4219
を参照して下さい。コマンドプロンプトを使う方法と、Visual Studioを使う方法を紹介します。
コマンドプロンプトを使う
cmdでもできなくはないですが、パスが通って楽に使える「開発者用コマンドプロンプトforVS2015」を使うと良いでしょう。VS2015インストール時に一緒に入っているので探してみてください。
任意のフォルダで、moduleを宣言しクラスや関数などをexportするファイルを作成します。このファイルの拡張子は.ixx
である必要があります。今回はcalc.ixx
という名前で作成しました。
次に以下のように記述します:
module calc; export { int add(int x, int y); int sub(int x, int y); } int add(int x, int y) { return x + y; } int sub(int x, int y) { return x - y; }
module calc;
で、この宣言以下のクラスや関数などがそのmoduleに所属します。exportブロックの中に、外部に公開したいクラスや関数を宣言します。これは、
module calc; export int add(int x, int y) { return x + y; } export int sub(int x, int y) { return x - y; }
のように個別に書くこともできます。そして、ファイルを作成したフォルダで
cl.exe /c /experimental:module calc.ixx
とclを実行します。すると同じフォルダにcalc.obj
とcalc.ifc
というファイルが作成されます。
(自分の実行結果例)
C:\Users\takuya\dev\ModuleTest_>cl.exe /c /experimental:module calc.ixx Microsoft(R) C/C++ Optimizing Compiler Version 19.00.23506 for x86 Copyright (C) Microsoft Corporation. All rights reserved. Experimental features are provided as a preview of proposed language features, and we're eager to hear about bugs and suggestions for improvements. However, note that these experimental features are non-standard, provided as-is without support, and subject to breaking changes or removal without notice. See http://go.microsoft.com/fwlink/?LinkID=691081 for details. calc.ixx C:\Users\takuya\dev\ModuleTest_>dir ドライブ C のボリューム ラベルがありません。 ボリューム シリアル番号は E24A-3B05 です C:\Users\takuya\dev\ModuleTest_ のディレクトリ 2015/12/02 06:38 <DIR> . 2015/12/02 06:38 <DIR> .. 2015/12/02 06:38 1,499 calc.ifc 2015/12/02 06:35 170 calc.ixx 2015/12/02 06:38 550 calc.obj 3 個のファイル 2,219 バイト 2 個のディレクトリ 806,601,965,568 バイトの空き領域 C:\Users\takuya\dev\ModuleTest_>
calc.ixxと同じフォルダにmain.cpp
を作成し、次のように書いてください:
#include <iostream> import calc; int main() { std::cout << add(1, 2) << std::endl; std::cout << sub(1, 2) << std::endl; }
そうしたらcalc.ixxと同じように
cl.exe /c /experimental:module main.cpp
と実行します。あとはobjをリンクすれば実行ファイルができます。
link *.obj
今回はcalc.exeが作成されたと思います。実行して
3 -1
と表示されたら成功です!
Visual Studioを使う
適宜、ソリューション、プロジェクトファイルを作成します。次にコマンドプロンプトを使う方法と同じファイルをプロジェクトに作成していくのですが、 calc.ixxというファイル名でファイルを作成するとプロジェクトのコンパイルを行うファイルに含まれないようになってしまいます。つまり、objが生成されずリンクエラーになってしまいます。
ixxファイルをコンパイルに追加するには、calc.ixxを右クリックし、プロパティを開きます。構成プパティ > 全般
から、項目の種類
をC/C++ コンパイラ
を選択します。これでcalc.ixxがコンパイルされるようになりました。(srz_zumixさんご指摘ありがとうございます)
calc.ixxとmain.cppの中身はコマンドプロンプトを使う方法と同じになりますのでそちらのサンプルコードを参考にしてください。
プロジェクトのプロパティを開き、構成プロパティ > C/C++ > コマンドライン
に/experimental:module
を追記します。
適用(A)
を押して閉じます。
次にixxファイルそれぞれをソリューションエクスプローラー上から右クリックし、プロパティを選択します。構成プロパティ > C/C++ > コマンドライン
に/c
を追記します。
適用(A)
を押して閉じます。
後は普段Visual Stuido上で開発を行うようにCtrl + F5なり、Ctrl + Shift + Bなり、F5なり押してビルドが成功、実行できるはずです。上手くいかない場合はプロジェクトのリビルドを試してみてください。ixxファイルを更新するたびにリビルドが必要な点が注意です。
まとめ
この記事で触れたことをまとめます。
- Visual Studio 2015でC++にmoduleが試験的に実装された
- moduleとは何か
- まだIDEのサポートは弱い
- 実際にmoduleを含んだコードをビルドする方法(CUIとGUIそれぞれ)
私もまだ試したいことをが色々ある(templateはできるのか、exportはネストできるのか(=com.hoge.util.func(1, 2)のようなことができるのか)等)ので、いじって遊んでみたいと思います。