简体   繁体   English

C++中POD类型的默认初始化

[英]Default initialization of POD types in C++

I know some POD variables are initialized by default, but others are not.我知道一些POD变量是默认初始化的,但其他的不是。 (POD types include int , float , pointers, unions, arrays of POD types, structs of POD types, etc.) (POD 类型包括intfloat 、指针、联合、POD 类型的数组、POD 类型的结构体等)

How does scope and storage class affect default initialization of POD types?范围和存储类如何影响 POD 类型的默认初始化?

Specifically, which of the following will be initialized implicitly:具体来说,以下哪些会被隐式初始化:

  • Local variables with automatic storage具有自动存储的局部变量
  • Static local variables静态局部变量
  • Static global variables静态全局变量
  • External variables外部变量
  • Variables allocated with newnew分配的变量
  • POD members of a class (without explicit initialization in a constructor)类的 POD 成员(在构造函数中没有显式初始化)

I know there are existing questions relating to some of these situations, but none comprehensive (they only address specific situations).我知道存在与其中一些情况相关的问题,但都不全面(它们仅针对特定情况)。

Local variables with automatic storage duration are not being initialized automatically.具有自动存储持续时间的局部变量不会被自动初始化。 Since using uninitialized variables produces undefined behavior , it is a good practice to explicitly initialize your variables even when it's redundant.由于使用未初始化的变量会产生未定义的行为,因此即使变量是多余的,显式初始化它也是一个好习惯。

About POD types that are being zero-initialized, C++03 standard 3.6.2 Initialization of non-local objects states:关于被零初始化的 POD 类型,C++03 标准3.6.2 非本地对象的初始化声明:

§1 Objects with static storage duration (3.7.1) shall be zero-initialized (8.5) before any other initialization takes place. §1具有静态存储持续时间(3.7.1) 的对象应在任何其他初始化发生之前进行零初始化(8.5)。 Zero-initialization and initialization with a constant expression are collectively called static initialization;零初始化和用常量表达式初始化统称为静态初始化; all other initialization is dynamic initialization.所有其他初始化都是动态初始化。 Objects of POD types (3.9) with static storage duration initialized with constant expressions (5.19) shall be initialized before any dynamic initialization takes place.具有用常量表达式 (5.19) 初始化的静态存储持续时间的 POD 类型 (3.9) 的对象应在任何动态初始化发生之前进行初始化。

So it's guaranteed by standard that POD types with static storage duration (whatever their scope is) will be zero-initialized.因此,标准保证具有静态存储持续时间(无论其范围如何)的 POD 类型将被零初始化。

POD members of a class (without explicit initialization in a constructor)类的 POD 成员(在构造函数中没有显式初始化)

This situation is described in 12.6.2 Initializing bases and members , that states (selected parts):这种情况在12.6.2 Initializing bases and members 中描述,其中指出(选定部分):

If a given nonstatic data member or base class is not named by a mem-initializer-id (including the case where there is no mem-initializer-list because the constructor has no ctor-initializer), then:如果给定的非静态数据成员或基类不是由 mem-initializer-id 命名的(包括由于构造函数没有 ctor-initializer 而没有 mem-initializer-list 的情况),则:

— If the entity is a nonstatic data member ..., and the entity class is a non-POD class, the entity is default-initialized (8.5)... — 如果实体是非静态数据成员...,并且实体类是非 POD类,则实体默认初始化(8.5)...

Otherwise, the entity is not initialized ... 否则,实体未初始化...

After the call to a constructor for class X has completed, if a member of X is neither specified in the constructor's mem-initializers, nor default-initialized, nor value-initialized, nor given a value during execution of the body of the constructor, the member has indeterminate value.在对类 X 的构造函数的调用完成后,如果 X 的成员既没有在构造函数的 mem-initializers 中指定,也没有被默认初始化,也没有被初始化,也没有在构造函数体的执行过程中给定值,该成员具有不确定的价值。

Example:例子:

class C
{
public:
    C(int x, int z) : x(x), z(z) { }
    int x, y, z;
};

int main(void)
{
    C* c = new C(1,3);
    std::cout << c->y; // value of y is undetermined !!!
}

If we're only talking about PODs then only local and global statics and external variables because they have to be defined somewhere.如果我们只讨论 POD,那么只有局部和全局静态以及外部变量,因为它们必须在某处定义。

PODs allocated with new are also initialized sometimes - if you make the initialization explicit:使用new分配的 POD有时也会被初始化 - 如果您明确初始化:

int* x = new int();

will create an int initialized to 0 with x pointing to it, whereas将创建一个初始化为0x指向它的int ,而

int* x = new int;

will have x point to an uninitialized int .将使x指向一个未初始化的int

Sometimes - POD class members - they can be initialized explicitly (without being in a constructor):有时 - POD 类成员- 它们可以显式初始化(​​无需在构造函数中):

struct X
{
   int x;
};

X x;        //x.x is not initialized
X y = X();  //y.x is 0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM