POD型のみをメンバに持つクラスのコンストラクタの挙動について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
GPGA

POD型のみをメンバに持つクラスのコンストラクタの挙動について

#1

投稿記事 by GPGA » 16年前

お世話になります。
POD型のみをもつclassまたは、structでコンストラクタ
デストラクタ、仮想関数を定義していない場合
メンバが0クリアされるという仕様がC++にはあるのでしょうか?

例えば
int* a = new int;		// 0クリアされない
int* a = new int();		// 0クリアされる

というのは、仕様として存在するのはわかりますが

class Hoge {
private :
	int a;
};
Hoge* hoge = new Hoge();

とした際に、aが0クリアされるのは仕様であるか、否かということです。

コスト的な面を考えると、これが仕様であることはあり得ないと思うのですが
VS2008では、HogeをPOD型とみなし、勝手に0クリアをしてしまうようです。
なお、CordWarriorでは0クリアされることはありませんでした。

以上、宜しくお願い致します。
 

Justy

Re:POD型のみをメンバに持つクラスのコンストラクタの挙動について

#2

投稿記事 by Justy » 16年前

 ゼロ初期化される、でいいのではないでしょうか。

 一応いつもの規格書(JIS X3014)を見てみると 12-6でクラス型のオブジェクトに対する
()による初期化の場合「値初期化」が行われるとあり、
「値初期化」は 8-5-5で「コンストラクタがない場合各非静的メンバを
値初期化する」とあり、そのメンバもコンストラクタもなく配列でもなければ
ゼロ初期化されるとあります。

 と、解釈しましたが、あってますかね?


 ところで、(今はどうかわかりませんが)Code Warriorって昔使った印象だと
C++への準拠度が低かったような気がします。
 上の解釈が正しければ、そのあたりが影響してるのかもしれません。

たかぎ

Re:POD型のみをメンバに持つクラスのコンストラクタの挙動について

#3

投稿記事 by たかぎ » 16年前

Justyさんの解釈であっています。
この辺りの仕様は、あちこちに分散して書かれているので分かりにくいですね。

GPGA

Re:POD型のみをメンバに持つクラスのコンストラクタの挙動について

#4

投稿記事 by GPGA » 16年前

なるほど、ありがとうございます。

でもそうすると、VCでデストラクタを定義した場合、メンバが初期化されないのは
規格に準拠していないってことになるんですかね?

YuO

Re:POD型のみをメンバに持つクラスのコンストラクタの挙動について

#5

投稿記事 by YuO » 16年前

PODの定義より,ユーザー定義のデストラクタがある場合はPOD型にはなりません。
# ISO/IEC 14882:1998およびINCITS/ISO/IEC 14882:2003 9 Classes / Paragraph. 4

で,ここからがややこしいのですが,
・ISO/IEC 14882:1998の記述
12.6 Initialization / Paragraph. 1
> When no initializer is specified for an object of (possibly cvqualified) class type (or array thereof), or the initializer has the form (), the object is initialized as specified in 8.5.
> [Note: if the class is a nonPOD, it is default-initialized.]
8.5 Initializers / Paragraph. 7
> An object whose initializer is an empty set of parentheses, i.e., (), shall be default-initialized.

・INCITS/ISO/IEC 14882:2003の記述
12.6 Initialization / Paragraph. 1
> When no initializer is specified for an object of (possibly cv-qualified) class type (or array thereof), or the initializer has the form (), the object is initialized as specified in 8.5.
> The object is default-initialized if there is no initializer, or value-initialized if the initializer is ().
8.5 Initializers / Paragraph. 7
> An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized.

この通り,2003年の改正でユーザー定義デストラクタを定義した場合における()初期化の扱いが変化しています。
# 1998年版にはそもそもvalue-initializeという考えがないのですが。
なので,発売時期から考えて,
・Visual C++.NETおよびVisual C++.NET 2003
標準規格は1998年版なので
「デストラクタがある場合はゼロ初期化を行う必要はない (暗黙のデフォルトコンストラクタを呼び出すから)」
・Visual C++ 2005, 同2008
標準規格は2003年版なので
「デストラクタがあってもゼロ初期化を行う必要がある」
となります。

このため,2005/2008において,
・ユーザー定義コンストラクタがない
・ユーザー定義デストラクタがある
・()付きの初期化を行った
という条件下でint型の非staticメンバの値がゼロにならないのであれば規格に準拠していないと言えます。
# って,/Za付きでもだめですが…… (2010含む)。

GPGA

Re:POD型のみをメンバに持つクラスのコンストラクタの挙動について

#6

投稿記事 by GPGA » 16年前

>YuOさん
なるほど、ややこしい仕様ですね。

こういう細かいところって、ネット上のあがってこないので
すごく勉強になりました。ありがとうございます。

閉鎖

“C言語何でも質問掲示板” へ戻る