views:

279

answers:

7
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?

+5  A: 

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 want your struct to be automatically initialized, you need to use a constructor:

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

Cogwheel - Matthew Orlando
+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).
+1  A: 

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.

Kotti
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
+1  A: 

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.

Donnie
This isn't true for C++. A simple `std::string s;` will certainly initialize `s`.
sbi
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.
Donnie
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
smerlin
+1  A: 

Have a default constructor:

struct foo {
    foo() : my_bool(false), my_int(0) {}
    bool my_bool;
    int  my_int;
};
tjm
+2  A: 

Implement a default constructor:

typedef struct foo 
{ 
    foo()
    : my_bool(false), my_int(0)
    {
        // Do nothing
    }
    bool my_bool; 
    int my_int; 
} foo; 
rturrado
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.
Craig W. Wright
+1  A: 

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.

Johannes Schaub - litb
+2  A: 

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.

AndreyT
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.
Stephen Blinkhorn