Default variable value

2018-12-31 22:27发布

问题:

If I don\'t assign a value to a variable when I declare it, does it default to zero or just whatever was previously in the memory?

e.g.

float x;

回答1:

A declared variable can be Zero Initialized, Value Initialized or Default Initialized.

The C++03 Standard 8.5/5 aptly defines each:

To zero-initialize an object of type T means:

— if T is a scalar type (3.9), the object is set to the value of 0 (zero) converted to T;
— if T is a non-union class type, each nonstatic data member and each base-class subobject
is zero-initialized;
— if T is a union type, the object’s first named data member is zero-initialized;
— if T is an array type, each element is zero-initialized;
— if T is a reference type, no initialization is performed.

To default-initialize an object of type T means:
— if T is a non-POD 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, the object is zero-initialized.

To value-initialize an object of type T means:
— if T is a class type (clause 9) with a user-declared constructor (12.1), then the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
— if T is a non-union class type without a user-declared constructor, then every non-static data member and base-class component of T is value-initialized;
— if T is an array type, then each element is value-initialized;
— otherwise, the object is zero-initialized

For example:

#include<iostream>
using namespace std;

static int a; //Zero Initialized
int b; //Zero Initialized

int main()
{
    int i;  //Undefined Behavior, Might be Initialized to anything
    static int j; //Zero Initialized

    cout<<\"\\nLocal Uninitialized int variable [i]\"<<i<<\"\\n\";

    cout<<\"\\nLocal Uninitialized Static int variable [j]\"<<j<<\"\\n\";

    cout<<\"\\nGlobal Uninitialized Static int variable [a]\"<<a<<\"\\n\";

    cout<<\"\\nGlobal Uninitialized int variable [b]\"<<b<<\"\\n\";

    return 0;
}

You will notice The results for variable i will be different on different compilers. Such local uninitialized variables SHOULD NEVER be used. In fact, if you turn on strict compiler warnings, the compiler shall report an error about it. Here\'s how codepad reports it an error.

cc1plus: warnings being treated as errors
In function \'int main()\':
Line 11: warning: \'i\' is used uninitialized in this function

Edit: As rightfully pointed out by @Kirill V. Lyadvinsky in the comments, SHOULD NEVER is a rather very strong word, and there can be perfectly valid code which might use uninitialized variables as he points out an example in his comment. So, I should probably say:
You should never be using uninitialized variables unless you know exactly what you are doing.



回答2:

It depends. If this is a local variable (an object with automatic storage duration) it will be uninitialized, if it is a global variable (an object with static storage duration) it will be zero initialized. Check also this answer.



回答3:

It depends on the lifetime of the variable. Variables with static lifetime are always zero-initialized before program start-up: zero-initialization for basic types, enums and pointers is the same as if you\'d assigned 0, appropriately converted to the type, to it. This occurs even if the variable has a constructor, before the constructor is called.



回答4:

This depends on where you declare it. Variables in the global scope are initialized with 0, and stack-variables are undefined.



回答5:

I think it\'s undefined. I think some compilers, when compiling in debug mode, initialize it to zero. But it\'s also ok to have it be whatever was already there in memory. Basically - don\'t rely on either behavior.

UPDATE: As per the comments - global variables will be zero-initialized. Local variables will be whatever.

To answer your second question:

Thanks - following on from this then, is there a shortcut to assign zero to all of the following?: float x1, x2, x3, x4, x5, y1, y2, y3, y4, y5

You could do

float x[5] = {0,0,0,0,0}; float y[5] = {0,0,0,0,0};

and use x[0] instead of x1.



回答6:

It can be compiler specific but generally release builds don\'t initialise variables to any particular value, so you get whatever is left in memory. Certain magic numbers are used in debug builds by some compilers to mark specific areas of memory however.



回答7:

Using the value of any variable prior to initialization (note that static-storage-duration objects are always initialized, so this only applies to automatic storage duration) results in undefined behavior. This is very different from containing 0 as the initial value or containing a random value. UB means it\'s possible that anything could happen. On implementations with trap bits it might crash your program or generate a signal. It\'s also possible that multiple reads result in different unpredictable values, among any other imaginable (or unimaginable) behavior. Simply do not use the value of uninitialized variables.

Note: The following was edited based on comments:

Note that code like this is invalid unless you can assure that the type foo_t does not have padding bits:

foo_t x;
int i;
for (i=0; i<N; i++) x = (x<<1) | get_bit();

Even though the intent is that the \"random value\" initially in x gets discarded before the loop ends, the program may invoke UB as soon as it accesses x to perform the operation x<<1 on the first iteration, and thus the entire program output is invalidated.



回答8:

C++ does not instantiate variables. The value of x is whatever happened to be in the memory at the time. Never assume anything about its initial value.



标签: c++ c