こんにちは高木です。
普段、ちょっとした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 |
近いうちに続編を書きたいと思いますので、あまり期待せずにお待ちください。