1. ホーム
  2. c++

[解決済み】C++で次のフレーズは何を意味するのか:ゼロ、デフォルト、値-初期化?

2022-04-11 01:14:47

質問

C++で次のフレーズは何を意味するのでしょうか。

  • ゼロ初期化。

  • デフォルト初期化、および

  • 値による初期化

C++開発者はこれらについて何を知っておくべきでしょうか?

どのように解決するのですか?

ひとつ認識しておいてほしいのは、「値初期化」はC++ 2003標準の新機能であり、オリジナルの1998標準には存在しないということです(明確化以上の違いはこれだけかもしれませんね)。 参照 Kirill V. Lyadvinskyの回答 をご覧ください。

の動作については、前回の回答をご覧ください。 operator new これらのタイプの初期化の動作の違いや、いつ起動するか(c++98 と C++03 で異なる場合)についての詳細は、こちらをご覧ください。

回答の要点は

new 演算子が返すメモリは、新規作成する型が POD であるか、POD メンバを含むクラスでコンパイラが生成したデフォルトコンストラクタを使用しているかによって、初期化されるときとされないときとがあります。

  • C++1998では、初期化にはゼロとデフォルトの2種類があります。
  • C++2003では、3種類目の初期化として、値の初期化が追加されました。

はっきり言って、かなり複雑で、それぞれのメソッドが効くタイミングも微妙です。

注意点としては、MSVCはVS2008(VC9またはcl.exeバージョン15.x)でもC++98のルールに則っていることです。

次のスニペットは、MSVCとDigital MarsがC++98のルールに、GCC 3.4.5とComeauがC++03のルールに準拠していることを示しています。

#include <cstdio>
#include <cstring>
#include <new>

struct A { int m; }; // POD
struct B { ~B(); int m; }; // non-POD, compiler generated default ctor
struct C { C() : m() {}; ~C(); int m; }; // non-POD, default-initialising m

int main()
{
    char buf[sizeof(B)];
    std::memset( buf, 0x5a, sizeof( buf));

    // use placement new on the memset'ed buffer to make sure 
    //  if we see a zero result it's due to an explicit 
    //  value initialization
    B* pB = new(buf) B();   //C++98 rules - pB->m is uninitialized
                            //C++03 rules - pB->m is set to 0
    std::printf( "m  is %d\n", pB->m);
    return 0;
}