お世話になります。 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クリアされることはありませんでした。 以上、宜しくお願い致します。
POD型のみをメンバに持つクラスのコンストラクタの挙動について
POD型のみをメンバに持つクラスのコンストラクタの挙動について
Re:POD型のみをメンバに持つクラスのコンストラクタの挙動について
ゼロ初期化される、でいいのではないでしょうか。
一応いつもの規格書(JIS X3014)を見てみると 12-6でクラス型のオブジェクトに対する
()による初期化の場合「値初期化」が行われるとあり、
「値初期化」は 8-5-5で「コンストラクタがない場合各非静的メンバを
値初期化する」とあり、そのメンバもコンストラクタもなく配列でもなければ
ゼロ初期化されるとあります。
と、解釈しましたが、あってますかね?
ところで、(今はどうかわかりませんが)Code Warriorって昔使った印象だと
C++への準拠度が低かったような気がします。
上の解釈が正しければ、そのあたりが影響してるのかもしれません。
一応いつもの規格書(JIS X3014)を見てみると 12-6でクラス型のオブジェクトに対する
()による初期化の場合「値初期化」が行われるとあり、
「値初期化」は 8-5-5で「コンストラクタがない場合各非静的メンバを
値初期化する」とあり、そのメンバもコンストラクタもなく配列でもなければ
ゼロ初期化されるとあります。
と、解釈しましたが、あってますかね?
ところで、(今はどうかわかりませんが)Code Warriorって昔使った印象だと
C++への準拠度が低かったような気がします。
上の解釈が正しければ、そのあたりが影響してるのかもしれません。
Re:POD型のみをメンバに持つクラスのコンストラクタの挙動について
Justyさんの解釈であっています。
この辺りの仕様は、あちこちに分散して書かれているので分かりにくいですね。
この辺りの仕様は、あちこちに分散して書かれているので分かりにくいですね。
Re:POD型のみをメンバに持つクラスのコンストラクタの挙動について
なるほど、ありがとうございます。
でもそうすると、VCでデストラクタを定義した場合、メンバが初期化されないのは
規格に準拠していないってことになるんですかね?
でもそうすると、VCでデストラクタを定義した場合、メンバが初期化されないのは
規格に準拠していないってことになるんですかね?
Re:POD型のみをメンバに持つクラスのコンストラクタの挙動について
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含む)。
# 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含む)。
Re:POD型のみをメンバに持つクラスのコンストラクタの挙動について
>YuOさん
なるほど、ややこしい仕様ですね。
こういう細かいところって、ネット上のあがってこないので
すごく勉強になりました。ありがとうございます。
なるほど、ややこしい仕様ですね。
こういう細かいところって、ネット上のあがってこないので
すごく勉強になりました。ありがとうございます。