typedef struct : Default Initialization

2020-02-17 08:23发布

问题:

typedef struct foo
{
    bool my_bool;
    int my_int;
} foo;

In the example above I understand that my_bool will be initialized randomly to either true or false but what about my_int? I assumed that my_int would be default initialized to 0 but that seems not to be the case.

Defining structs in this way appears to be incompatible with initialization lists so what is the best way to initialize my_bool and my_int to false and 0 respectively?

回答1:

Types don't get "initialized". Only objects of some type get initialized. How and when they get initialized depends on how and where the corresponding object is defined. You provided no definition of any object in your question, so your question by itself doesn't really make much sense - it lacks necessary context.

For example, if you define a static object of type foo

static foo foo_object; // zeros

it will be automatically zero-initialized because all objects with static duration are always automatically zero-initialized.

If you define an automatic object of type foo without an initializer, it will remain uninitialized

void func()
{
   foo foo_object; // garbage
}

If you define an automatic object of type foo with an aggregate initializer, it will be initialized in accordance with that initializer

void func()
{
   foo foo_object1 = { 1, 2 }; // initialized
   foo foo_object2 = {}; // initialized with zeros
}

If you allocate your object with new and provide no initializer, it will remain uninitialized

foo *p = new foo; // garbage in `*p`

But if you use the () initializer, it will be zero-initialzed

foo *p = new foo(); // zeros in `*p`

If you create a temporary object of type foo using the foo() expression, the result of that expression will be zero-initialized

bool b = foo().my_bool; // zero
int i = foo().my_int; // zero

So, once again, in your specific case the initialization details depend on now you create the object of your type, not on your type itself. Your type itself has no inherent initialization facilities and doesn't interfere with the initialization in any way.



回答2:

Implement a default constructor:

typedef struct foo 
{ 
    foo()
    : my_bool(false), my_int(0)
    {
        // Do nothing
    }
    bool my_bool; 
    int my_int; 
} foo; 


回答3:

First off, the way that struct is declared is in the style of C. In C++ you should just do:

struct foo 
{
    bool my_bool;
    int my_int;
};

In both C and C++, initialization is a separate step from allocation. If you always want to initialize the members of your struct, use default initialization syntax like this:

struct foo
{
    bool my_bool{};
    bool my_int{};
};

In older versions of C++ you need to manually write a default constructor that initializes all the members (the newer syntax above is just sugar for this):

struct foo 
{
    foo() : my_bool(), my_int() { }
    bool my_bool;
    int my_int;
};

As @sbi notes, if you want to manually initialize the struct, even without the default constructor, you can do foo myFoo = foo();



回答4:

Have a default constructor:

struct foo {
    foo() : my_bool(false), my_int(0) {}
    bool my_bool;
    int  my_int;
};


回答5:

You are not creating any object in that code. Initialization is done when you create objects, and is not particularly tucked by the way you declare the struct.

For instance the following initializes the boolean to false and the integer to 0

foo f = { };

Notice that you have just typdefed your struct. You have not created an object. Like others said you can omit the typedef in C++ and just declare the struct, and you are still able to refer to the type by just saying foo.

If you omit explicit initialization when you define an object, then for sure no initialization is done unless the object is defined at namespace scope or defined as static locally (in which case all members are zero-initialized) or the class has a user defined default constructor that does initialization accordingly.



回答6:

As long as you are declaring the structs in a C-way, you could use zeromemory to null exactly sizeof(foo) bytes, therefore defaulting all values to 0.

In C++, you could define your structure with a constructor which would set your values to some default values if needed.



回答7:

c and c++ don't initialize variables at all. They contain whatever happened to be in the memory location that they're now in previously. This also applies for member variables in classes and structs unless you specifically initialize them to a value.