Вопрос

When will a fundamental C++ type, such as int or float, have an unknown initial value?

How does the type of memory allocation factor in, if at all? What about the declaration? What if it's a member of a class/struct/union? Is C++11 different from C++03 or C++98?

I have my suspicions, but no idea if my knowledge is complete (or correct, for that matter)

Это было полезно?

Решение

Any POD data (including all fundamental types) will have an unknown value when both:

  • it doesn't have static memory allocation (it's instead created on the stack or with new)
  • it isn't initialized, including empty initialization and/or constructor initialization lists

Global/static variables, of all types, are set to zero as part of the startup process before main is called. Constructors are called for types that have constructors before main 1.

Anything not initialized in the constructor is also unknown.

Edit: to clarify, std::string is a good example of "constructor not initializing everything" - if you have a local std::string str;, then str will have a defined "empty string" content, but the content of the actual buffer, or indeed what the buffer points at may not be set to anything meaningful at all - as the implementation may determine based on the length [or some other way] whether there is a buffer available or not once we start using the string to store stuff].

Edit2: As the comment explains, you can also have "hybrid" cases, where parts of a structure is being initialized, e.g. a struct that contains some elements of "plain data" and some elements that have constructors. The ones that have constructors will have their constructor called. The plain data will not be initialized.

1 It may well be that the code running constructors is part of, or called from inside the "main" function - but if that is the case, it will be "before any of your code in main is started".

Другие советы

From "Working Draft C++, 2012-11-02"

3.6.2 Initialization of non-local variables [basic.start.init]
2 Variables with static storage duration (3.7.1) or thread storage duration (3.7.2) shall be zero-initialized (8.5) before any other initialization takes place.

Variables with static storage are at least zero initialized.

3.7.3 Automatic storage duration [basic.stc.auto]
2 [ Note: These variables are initialized and destroyed as described in 6.7. — end note ]

6.7 says nothing about how automatic variables are initialized.

3.7.4 Dynamic storage duration [basic.stc.dynamic]
...
3.7.4.1 Allocation functions [basic.stc.dynamic.allocation]
... There are no constraints on the contents of the allocated storage on return from the allocation function. The order, contiguity, and initial value of storage allocated by successive calls to an allocation function are unspecified.

8.5 Initializers [dcl.init]
7 To default-initialize an object of type T means:
— if T is a (possibly cv-qualified) class type (Clause 9), the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
— if T is an array type, each element is default-initialized;
— otherwise, no initialization is performed.

If you provide an explicit initializer, any variable will have a known value.

If you don't provide an explicit initializer for a POD type, it depends on the storage class. Static or thread variables will be zero initialized, whereas automatic or dynamically allocated variables are not.

If you have a compound type, the same rules apply. If you have don't have an explicit initializer, through a (default) constructor or otherwise, the initial value of fundamental types depends on the storage class.

Finally, memory allocated through malloc will be uninitialized, whereas calloc memory will be zero initialized.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top