typedef struct : Default Initialization

53,845

Solution 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.

Solution 2

Implement a default constructor:

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

Solution 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();

Solution 4

Have a default constructor:

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

Solution 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.

Share:
53,845
Stephen Blinkhorn
Author by

Stephen Blinkhorn

Mostly audio and DSP related development. Developer at AudioSpillage.

Updated on January 07, 2020

Comments

  • Stephen Blinkhorn
    Stephen Blinkhorn over 4 years
    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?

  • sbi
    sbi almost 14 years
    And if later someone adds double my_fpn;, then this might fail on an implementation where a double with all bits set to zero isn't a valid floating point number.
  • sbi
    sbi almost 14 years
    This isn't true for C++. A simple std::string s; will certainly initialize s.
  • Donnie
    Donnie almost 14 years
    std::string creates an object and calls its constructor and initializes it explicitly. It may be a technical difference, but my statement remains correct. In this case he could create a constrictor for his struct and get the same behavior. Does that mean it's being initialized automatically? No, not really.
  • smerlin
    smerlin almost 14 years
    you dont have to initialize it to a value e.g. int i = int(); calls the "default constructor" of int, and therefore initializes i to the default value of 0
  • Stephen Blinkhorn
    Stephen Blinkhorn almost 14 years
    I usually create an automatic object by simply doing 'foo a_foo;' ..and then follow up with 'a_foo.my_bool = true;' With larger structs I don't always want to set say 5-6 members manually.
  • Craig Wright
    Craig Wright almost 14 years
    I think this is much better that depending upon implicit initialization of data members. Most especially if you happen to be writing platform neutral code. Even if you expect all compilers to behave identically, it's still good to be explicit about your intent. It aids readability, maintainability, and helps those who come after you.
  • stinky472
    stinky472 almost 14 years
    +1. Aside from being in the style of C, I'd go so far as to say that it's a bad style even in C (as common as it is). Peter van der Linden goes in depth about this in the butt ugly fish book, but writing struct foo is not hard to write and provides one consistent name for the type that's easier to forward declare (instead of something like struct st_foo and a foo typedef for it).