こんにちは高木です。
普段、ちょっとしたC++のプログラムを書くときはmsys2上でMinGW-w64を使っています。最近、ようやくpacmanでインストールできるGCCのバージョンが11.2になりましたので、実験的にC++20のコードを書いてみることにしました。C++20になってもお題はTcl/Tkです。
いきなり難しいことはできませんので、今回は簡単なことだけにとどめます。それでも、C++20らしさを出すため、モジュールとchar8_t型のモジュールを使ってみることにしました。とりあえず、適当に書き殴ったコードを貼り付けます。
| 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | // tk.cc module; #include <tk.h> export module Tk; namespace tk {   export int run(char const* argv0, char8_t const* script)   {     Tcl_FindExecutable(argv0);     auto interp = Tcl_CreateInterp();     Tcl_Init(interp);     Tk_Init(interp);     Tcl_Eval(interp, reinterpret_cast<char const*>(script));     Tk_MainLoop();     Tcl_Finalize();     return 0;   } } | 
| 0 1 2 3 4 5 6 7 8 9 | // main.cc #include <tcl.h> import Tk; int main(int argc, char const* argv[]) {   tk::run(argv[0], u8"pack [button .b -text exit -command exit]"); } | 
GCCでモジュールを使ったのは今回が初めてだったのですが、私が悪いのか、コンパイラのバグなのか、よくわからないエラーが出て悩まされました。具体的にはrun関数の引数としてstd::functionを渡してrunの中で呼び出すとbad_alloc例外が発生してしまいます。夜遅くに深追いするのも嫌だったので、今回はスクリプトを単なる文字列として渡すだけにしました。
TclのAPIに渡す文字列はchar型の文字列ですが、期待するエンコーディングはUTF-8です。C言語の場合はそれも仕方がないところですね。しかし、char型の文字列ではUTF-8に強制することはできませんので、char8_t型の文字列を渡して、run関数の中でchar const*にキャストしています。
モジュールについては正直もっと勉強しないといけませんね。それと、コンパイラやIDEの完成度がもっと上がらないといけないとも思います。
ちなみに今回のコードをコンパイルするときに使ったコマンドは以下の通りです。
| 0 1 2 | g++ -fmodules-ts -std=gnu++20 main.cc tk.cc -ltcl -ltk | 
近いうちに続編を書きたいと思いますので、あまり期待せずにお待ちください。





![[迷信] 引用符で囲んだヘッダ名はカレントディレクトリから探索する](https://www.kijineko.co.jp/wp-content/uploads/2021/06/5064715_s.jpg)
