JIS X3014の値初期化の記述に悩まされる

すでに誰かが指摘していることなのだとは思いますが、JIS X3014:2003の「値初期化」の記述にさんざん悩まされました。今回は非常にデリケートな話なので、規格からの引用は転記でなく、キャプチャ画像を貼ることにします。

まず、順を追ってお話することにします。C互換型ではないクラス型の初期化について確認しようと思い、JIS X3014:2003の12.6 初期化に目を通しました。

12.6 初期化
 

これによると、初期化子が()の場合は「値初期化」されることになっています。つまり、std::string()のような記述を行った場合は値初期化されるわけです。

次に、値初期化について確認しようと思い、8.5 初期化子の記述に目を通しました。

8.5 初期化子

 

8.5 初期化子の値初期化の記述によると、std::stringは利用者定義コンストラクタを持ち、配列型でもありませんから、三つめの「そうでない場合〜」に該当します。ですので、ゼロ初期化されるわけです。そして、ゼロ初期化の記述を見ると、std::stringは共用体ではないクラス型ですので二つめの記述になります。つまり、非静的メンバをゼロクリアする、以上。となるわけです。

ちょっと待って! ということは、std::string()とした場合、コンストラクタは呼ばれないことになってしまいます。そんなバカなことはないはずです。実際にテストコードを書いて試しても、ちゃんとコンストラクタは呼ばれます。目を皿のようにして記述を何度も読みなおしましたが、そうとしか解釈できません。

まさかとは思いましたが、念のためISO/IEC 14882:2003も確認してみることにしました。すると、すべての謎が解けました。

8.5 Initializers
 

ISO/IEC 14882の原文では、

To value-initialize an object of type T means:
— if T is a class type (clause 9) with a user-declared constructor (12.1), then the default constructor for T is
called (and the initialization is ill-formed if T has no accessible default constructor);
— if T is a non-union class type
without a user-declared constructor, then every non-static data member
and base-class component of T is value-initialized;
— if T is an array type, then each element is value-initialized;
— otherwise, the object is zero-initialized
A program that calls for default-initialization or value-initialization

となっており、JIS X3014の和訳では、上記の強調部分の記述がごっそり欠落しているではありませんか! これではいくら読んでも理解できるはずがありません。JIS X3014には誤訳がところどころあることは知っていましたが、これはあまりにも酷いですね。

この記事のトラックバックURL:

http://www.kijineko.co.jp/trackback/680
このエントリーを含むはてなブックマーク