wchar_t

何のためにあるのかちょっとわからなくなってきたので調べてみた。とりあえず規格の最新の draft によると、

5 Type wchar_t is a distinct type whose values can represent distinct codes for all members of the largest extended character set specified among the supported locales (22.3.1). Type wchar_t shall have the same size, signedness, and alignment requirements (3.11) as one of the other integral types, called its underlying type. Types char16_t and char32_t denote distinct types with the same size, signedness, and alignment as uint_least16_t and uint_least32_t, respectively, in , called the underlying types.

5 wchar_t 型はサポートするロカール ( 22.3.1 ) のうち最大の拡張文字集合のすべての文字をその値が別個の符号で表現できる独立した型である。 wchar_t 型は { 基底型: underlying type } と呼ばれる、他の汎整数型のひとつと同じ容量、同じ符号、同じ配置要件 ( 3.11 ) を持たなければならない。 char16_t 型と char32_t 型はそれぞれ、 で定義され、基底型と呼ばれている uint_least16_t 型と uint_least32_t 型と同じ容量、同じ符号、同じ配置を持つ独立した型を意味している。

2010-02-16 Working Draft, Standard for Programming Language C++ 3.9.1

ってなことらしく、要は wchar_t object ひとつが文字ひとつに対応することが約束されている型ということらしい。ということはもろもろの文字列操作が非常に単純になるからうれしいわけだ。逆を言うと文字列操作しない場合 ( 文字列を使っても表示するだけとか ) は無理にこれを使わなくてもいいわけだな。あとは program 内部からのみ文字列が供給されるなら literal で書いてしまえばいいわけだど、例えば command line や file なんかの外部から文字列操作したいものが渡される場合そいつらが wchar_t に対応するような形式じゃないときは文字列操作をする前に変換するって処理が必要なわけだな。んー、これ Perl みたいに program への入力がされた時点で変換してしまう、という rule をもうけたほうが楽な気がするな。

いやでも file から読み込む場合はともかく command line については規格だけでは multibyte 文字列しか想定されてないのか。

2 An implementation shall not predefine the main function. This function shall not be overloaded. It shall have a return type of type int, but otherwise its type is implementation-defined. All implementations shall allow both of the following definitions of main:

int main() { /* ... */ }

and

int main(int argc, char* argv) { /* ... */ }

In the latter form argc shall be the number of arguments passed to the program from the environment in which the program is run. If argc is nonzero these arguments shall be supplied in argv[0] through argv[argc-1] as pointers to the initial characters of null-terminated multibyte strings (NTMBSs) (17.5.2.1.4.2) and argv[0] shall be the pointer to the initial character of a NTMBS that represents the name used to invoke the program or "". The value of argc shall be non-negative. The value of argv[argc] shall be 0. [ Note: it is recommended that any further (optional) parameters be added after argv. -end note ]

2 実装は main 関数を前もって定義してはならない。この関数はオーバーロードされてはならない。 int 型の返り値を持たなくてはならず、それ以外の場合その型は実装時定義である。すべての実装は以下の main の定義の両方を許可しなければならない。

int main() { /* ... */ }

もしくは

int main(int argc, char* argv) { /* ... */ }

後者において形式名 argc はプログラムを実行する環境からプログラムに渡された引数の数でなければならない。 argc が零でない場合これらの引数は終端が空値のマルチバイト文字列 ( NTMBS ) ( 17.5.2.1.4.2 ) の最初の文字へのポインター argv[0] から argv[argc-1] として提供されなければならず、 argv[0] はプログラムを起動するために使われた名前もしくは "" を表現する NTMBS の最初の文字へのポインターでなければならない。 argc の値は非負でなければならない。 argv[argc] の値は 0 でなければならない。 [ 注: argv の後ろに ( 任意の ) パラメーターを追加しないことを推奨する。 ]

2010-02-16 Working Draft, Standard for Programming Language C++ 3.6.1

てことは argv の中身に対して文字列操作する場合はまず真っ先に wchar_t 型へ変換してやらないといけないわけだな。あーでも VC++ のようにそこらへん変換済みで渡してくれる実装もあるからそれはそれで使えばいい、と。んーでもこれ将来的に wide character が native で mutibyte character なんて知りませんていう system が出てきたらどうすんだろう。 char は 1 byte 固定だから代わりにはならんだろうしな…。

1 The sizeof operator yields the number of bytes in the object representation of its operand. The operand is either an expression, which is an unevaluated operand (Clause 5), or a parenthesized type-id. The sizeof operator shall not be applied to an expression that has function or incomplete type, to an enumeration type whose underlying type is not fixed before all its enumerators have been declared, to the parenthesized name of such types, or to an lvalue that designates a bit-field. sizeof(char), sizeof(signed char) and sizeof(unsigned char) are 1. The result of sizeof applied to any other fundamental type (3.9.1) is implementation-defined. [ Note: in particular, sizeof(bool), sizeof(char16_t), sizeof(char32_t), and sizeof(wchar_t) are implementation-defined.73 -end note ] [ Note: See 1.7 for the definition of byte and 3.9 for the definition of object representation. -end note ]

73) sizeof(bool) is not required to be 1.

1 sizeof 演算子はその演算対象のオブジェクト表現におけるバイト数を与える。演算対象は評価されていない演算対象 ( 5 条 ) もしくは括弧で括られた型識別子のどちらでも良い。 sizeof 演算子は関数もしくは不完全型を持つ式、すべての列挙子が宣言される以前の基底型が固定でない列挙型、そのような型の括弧で括られた名前、ビットフィールドを指定する左辺値に適用されてはならない。 sizeof(char) 、 sizeof(signed char) 、 sizeof(unsigned char) は 1 である。他の基本型 ( 3.9.1 ) に sizeof を適用した結果は実装時定義である。 [ 注: 特に、 sizeof(bool) 、 sizeof(char16_t) 、 sizeof(char32_t) 、 sizeof(wchar_t) は実装時定義である 73 。 ] [ 注: バイトの定義は 1.7 を、オブジェクト表現の定義は 3.9 を参照せよ。 ]

73) sizeof(bool) は 1 である必要はない。

2010-02-16 Working Draft, Standard for Programming Language C++ 5.3.3

いやいや network 的なことを考えると multibyte character を知らない system なんて存在し得ないだろjkという仮定なのか ?

んーとりあえず文字列操作をする場合に wchar_t へ変換しとけばおkという理解でいいか。