※初投稿且つ一夜漬けなので細かいところは許してください
前置き
環境
- windows10
- visual studio 2022
なぜなに
無名名前空間について苦悩していたんですが,c++にはモジュールという便利機能があることを発見したのです.
しかし,c++20であったのです.
問題
まずwindowsな点です(ひどい)
また,別にc++20である程度ならいいのですが,モジュールはコンパイル関係だけあって対応が難しかったんですね(とかいいながらclangもgccももう対応してくれている)
問題解決
ということでいろいろサイトを漁った結果,問題は全部解決しました.
clangもgccももう対応しているという話なのですが,今回はMicrosoftさんが力を入れてモジュールに対応してくれているという話なので,Visual Studio 2022を使っていきたいと思います.
準備
まずVisual Studioを立ち上げます.
次に「新しいプロジェクトの作成」を選択し,「空のプロジェクト」を作成します.
名前は適当にしてさくっと作成します.
作成したらとりあえず,ソリューションエクスプローラー(なかったら右上当たりの検索っぽいやつから検索してください)内のソリューションの一個下のプロジェクトを右クリックして,プロパティを選択します.
※構成,プラットフォームに気を付けてください
その後は構成プロパティ > C/C++ > 言語 > C++言語標準が「既定(ISO C++14 標準)」になっていると思うので,
「ISO C++20 標準 (/std:c++20)」を選択します.
次にC++言語標準の下3個目(一番下)にある,「試験段階の C++ 標準ライブラリ モジュールを有効にする」をはいにします.
これであとは思う存分モジュールができます.
コンパイル
ということで試してみましょう
まず,ソースファイルとヘッダーファイルとC++モジュールインターフェースユニット(.ixx)を
追加 > 新しい項目 から追加します.
# include <iostream> // 古臭いコード
import <iostream>; // モダンなコード
因みにこれで#includeとかいう再インクルードしまくるゴミから解放されます.といっても現在ではまだ対応していませんが....
お試しコード
ということで適当にC++20の要素を詰めながらコードを書いてみました.Moduleの仕様に触れるように作ったんですが...途中で試してみたら,これが通らない!!原因はなんと不明です.具体的にはこれですね.linterさんは何の問題もないとおっしゃってるのに....
1>C:\Users\nziq5\source\repos\c++20\Hello_C++20_Module\Hello_C++20_Module\Source.cpp(1,1): fatal error C1001: 内部コンパイラ エラーが発生しました。
1>(コンパイラ ファイル 'msc1.cpp'、行 1687)
1> この問題を回避するには、上記の場所付近のプログラムを単純化するか変更してください。
1>可能な場合、再現手順をこちらに入力してください: https://developercommunity.visualstudio.com
1>詳細については、Visual C++ ヘルプ メニューのサポート情報コマンドを
1>選択するか、サポート情報ヘルプ ファイルを参照してください
1>'C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.30.30705\bin\HostX86\x86\CL.exe' で内部コンパイラ エラーが発生しました。
1> Visual C++ のサポート情報 コマンドを選択してください
1> ヘルプ メニュー、またはサポート情報のヘルプ ファイルを参照してください
1>プロジェクト "Hello_C++20_Module.vcxproj" のビルドが終了しました -- 失敗。
無名名前空間の代わりにだとか,あくまでexportだけだとか言おうと思っていたんですが,そもそもダメでした...力尽きたので原因解明はこれを読んでる方に託しときます.
これでただの文法の思い違いだったら恥ずかしすぎる.例えばexportは全てに付けなければならないとか
作ったコードの全貌
(下記をクリック)
# include <iostream>
# include <string>
using std::u8string;
consteval unsigned nn(const unsigned i = 1, unsigned k = 1) {
unsigned j = 1;
for (unsigned n = 0; n < k; ++n) j *= i;
return j;
}
const u8string str = u8"回目の「";
const unsigned i = nn (5, 7);
inline namespace header {
using std::cout;
using std::endl;
using std::string;
namespace impl {
string str;
static unsigned u = 0;
bool is_utf8_multibyte_code_unit(char c) {
return static_cast<unsigned char>(c) >= 0x80;
}
}
export void PrintHello(string str = "Hello!", unsigned u = 0) {
using namespace impl;
cout << u
<< reinterpret_cast<char>(::str.c_str()) // u8stringからchar8_t*からchar
<< impl::str << reinterpret_cast<char>(u8"」📃")
<< endl;
impl::str = str;
impl::u += u;
}
}
module;
# include "Header.hpp"
export module Module;
inline namespace module_ {
inline namespace header {
export void PrintHello(string, unsigned);
}
}
import Module;
inline namespace tmp {
int main () {
// PrintHello (); 何故かエラー
PrintHello ("Hello", 1);
}
}
とりま力尽きたのでここまで.
知りたいことがあったら参考全部載せるので自力か他力でどうぞ.
参考
モジュール関連
https://docs.microsoft.com/ja-jp/cpp/cpp/modules-cpp
https://stackoverflow.com/questions/67393131/unable-to-import-c-modules
https://logicalbeat.jp/blog/6223/
https://mahori.jp/2021/04/05/cpp-std-u8string/
https://onihusube.hatenablog.com/entry/2021/05/28/214612
https://cpprefjp.github.io/lang/cpp20/modules.html
https://vector-of-bool.github.io/2019/03/31/modules-2.html
https://stackoverflow.com/questions/64877559/cant-use-iostream-as-module-in-c20-visual-studio
(個人的に)モジュールの実行関連
https://blog.imfing.com/2020/06/cpp-20-modules-hello-world/
https://itnext.io/c-20-modules-complete-guide-ae741ddbae3d
https://devblogs.microsoft.com/cppblog/standard-c20-modules-support-with-msvc-in-visual-studio-2019-version-16-8/
https://docs.microsoft.com/ja-jp/archive/msdn-magazine/2016/april/visual-c-microsoft-pushes-c-into-the-future
https://stackoverflow.com/questions/59447206/standard-way-of-importing-modules
https://docs.microsoft.com/en-us/cpp/cpp/modules-cpp