views:

675

answers:

4

C++: Since a struct is a class with everything "public", are default -ctors created and called?

The reason I ask is to understand the overhead, if any, that C++ may have over C, when structs are used. An opinion I have heard is that classes have some overhead that structs don't, in C++, but I question this.

+14  A: 

In C++ there's no difference except the default visibilty of struct members is public, while class members default to private.

In terms of performance, struct construction will be just as fast as class construction. Actual speed will of course depend on what your struct contains. If you are moving a C struct to C++, your struct will only contain POD types (plain old data - no classes), which don't have constructors anyway.

Roddy
I thought in the absense of an explicit constructor, C++ created an implicit one that basically constructed all the members in a piecewise manner.
Shane MacLaughlin
It does, but not if the struct contains only POD (which is called a trivial constructor usually).
Greg Rogers
Be careful when using the "new" operator to instantiate structs. Depending on your compiler (e.g., MSVC), if your struct contains class types, their default constructors will not always be called. The problem is that compilers don't always value-initialize like they should.
Kurt
+1  A: 

Good question! My reading of Stroustrup would tend agree with Roddy's answer. However, I think whether or not the ctor is called depends to a certain extent on how the struct is created. For example, if you create the structs via malloc, I don't believe the constructor is called, whereas if you new them, I guess it would.

That said, I haven't actually checked the above.

Shane MacLaughlin
I'm not sure if a constructor is called on a _class_ (as opposed to a struct) when memory is malloc'd either. I think that's one of the main differences between malloc and new.
Onorio Catenacci
Calling malloc() just allocates memory. It has absolutely *nothing* to do with object construction.
Roddy
Roddy is correct. malloc() simply allocates a chunk of memory. To make it an object, you would then cast (better reinterpret_cast) the pointer to that memory to the pointer of the class you need, and the constructor is never called.
Dima
Roddy is right, malloc only knows how many bytes you want. But rather than casting to an object as Dima suggests, the correct thing to is to use placement new to ensures that ctors are called.
jwfearn
I agree with Roddy.
paercebal
+1  A: 

In Stroustrup's book, The C++ Programming Language, Special Edition, on page 234 section 10.2.8, he gives an example of a struct with a constructor. He also says a little further down in the text "Constructors and access functions can be quite useful even for such structures . . ." although I don't believe he's using the word "structures" in the strict technical sense. So I would guess that a struct does have a default constructor.

Onorio Catenacci
+10  A: 

structs do have a default constructor, under exactly the same circumstances that classes do.

By the way, a struct isn't "a class with everything public". It's a class with public as the default access specifier. structs can have private members, but your code reviewer might punch you if they do.

The relevant issue isn't struct vs. class, it's POD vs. non-POD.

Remember how an "int" member of a class is uninitialized unless you give it a value in the initializer list or set a value in the constructor? Well, the same applies to all POD types. The default constructor for a POD struct (or a POD class, for that matter) has nothing to do. So, although it nominally exists, a compiler shouldn't actually generate and call it.

This means that the default constructor for any type that you could have defined in C, should introduce no runtime overhead when used in C++. In practice, I hear rumours that not all C++ compilers apply enough optimisation to ensure that all code always emits a binary as good as it would have done if compiled as C. But I don't know whether this is ever one of the issues causing problems - I'd guess that it's usually identical.

So, given a POD struct:

struct sPOD {
    int foo;
    float bar;
    char baz[23];
};

The following is likely to emit no code in C++ (other than maybe moving the stack pointer, depending how much the compiler rolls automatic variables together), just like in C:

sPOD s1;

Indeed it doesn't for me on gcc.

Steve Jessop
Best Answer. Constructor is always created. It is just that an inlined function that does nothing does not generate much code. As long as all members are POD its a noop.
Martin York