1.6K Views
June 21, 25
スライド概要
C++ breaktime 2025/Summerの発表資料です。
C++20未満でもUTF-8型 を使いたかった @zbdk
C++の文字列 ■ UTF-8文字列を表す型が欲しい – 今までcharにASCII or SJIS or UTF-8が混在 – SJISとUTF-8を区別したい ■ char8_t型(C++20~) – 当時コンパイラがC++20に対応していなかった ■ C++20までのつなぎとして自前の型を用意した
UTF-8文字列リテラル ■ u8”text”の表す型 – C++11~C++17 ■ const char[N] – C++20~ ■ const char8_t[N]
C++20移行 ■ マクロを用意してスムーズに移行できるよう用意
ちょっとまって ■ これってStrict Aliasingルールに違反してる? ■ Strict Aliasingルール – 異なる型にキャストする際にユーザー側が守らないと いけないルール
Strict Aliasingルール ■ 本人が自認する型とは異なる型としてアクセスしては いけない オレ float float value float int intとしてアクセス キャスト reinterpret_cast<int*>(&value) 逆参照 *
今回のケース ■ 文字として使う場合にcharに戻して使っていたのでOK ~C++17 オレ char charとしてアクセス u8”text” char mychar8_t const char* msg キャスト キャスト 関数引き渡し const UTF8* msg_u8 do_something(const UTF8*) ※pointer-interconvertibleを満たすべきなのかは調べきれませんでした
C++20になると? ■ ルール違反していそうだがcharは例外的にアクセス可能 C++20~ charとしてアクセス const char* msg char char8_t キャスト オレ char8_t 関数引き渡し u8”text” do_something(const UTF8*)
その後 ■ いつの間にかu8stringが生まれていた – using u8string = std::basic_string<UTF8>; ■ そして最近 – 「Xcodeのバージョン上げたらu8stringがエラーに なったんですけど」 – 新しいClangさんが「char_traitsに文字型以外の型を入 れんじゃねぇよ」と言うようになった – さらにXcodeのバージョンを上げたらエラーは出なく なった
まさにこれ
おわりに ■ みんなC++20以降を使おう! ■ こんな型作ったよ~、というゆるふわな内容にしようと 思っていたのにどうしてこんな内容に・・・
おまけ スライド作ったけど発表からは省いたやつ
これは合法 ■ Strict Aliasingルールに則った書き方 – charへキャストしてのアクセスはOK – あるいはmemcpy
mychar8_tでできないこと ■ 文字列リテラルの連結 – auto* lit = U8_TEXT(“aaa”) U8_TEXT(“bbb”); ■ mychar8_t配列の文字列初期化 – UTF8 arr1[] = U8_TEXT(“arr”); ■ なんでそんなことするんですか? – UTF8 arr2[] = {UTF8('a'), UTF8('r'), UTF8('r'), UTF8('\0’)}; ■ さすがにこれは提案できなかった ■ arr2の文字たちは「オレmychar8_t」と思って生きている のにも注意