Comments on: Trivial Constructors and Destructors in C++ [...] recent post in AltDevBlogADay by Michael Tedder <Trivial Constructors and Destructors in C++> talked about creating POD data (Plain old data – i.e. data that has no virtual function [...] [...] recent post in AltDevBlogADay by Michael Tedder <Trivial Constructors and Destructors in C++> talked about creating POD data (Plain old data – i.e. data that has no virtual function [...]

]]>
By: Implementing a True realloc() in C++ « #AltDevBlogADay/2011/05/13/trivial-constructors-and-destructors-in-cpp/#comment-6357 Implementing a True realloc() in C++ « #AltDevBlogADay Sun, 26 Jun 2011 12:51:15 +0000 Interesting trick. What about using a static builder method to build your POD object (i.e. vector)? Wouldn't that have the "same effect" (of course that's a matter taste)? Interesting trick.
What about using a static builder method to build your POD object (i.e. vector)? Wouldn’t that have the “same effect” (of course that’s a matter taste)?

]]>
By: Jeremiah/2011/05/13/trivial-constructors-and-destructors-in-cpp/#comment-4569 Jeremiah Thu, 19 May 2011 15:48:46 +0000 Did a quick test and VS 2008 linktime generator optimises out simple constructors completely even if the constructor is safetly tucked away in a separate cpp file... I expect most compilers could at least deal with inline empty constructors - not sure there is any valid reason not to inline an empty constructor anyway. Both initialiser lists and simple array declarations generate identical code wether this is an empty constructor or not. Though, as you point out, there is still the advantage of being able to use POD types in unions. Did a quick test and VS 2008 linktime generator optimises out simple constructors completely even if the constructor is safetly tucked away in a separate cpp file… I expect most compilers could at least deal with inline empty constructors – not sure there is any valid reason not to inline an empty constructor anyway. Both initialiser lists and simple array declarations generate identical code wether this is an empty constructor or not.

Though, as you point out, there is still the advantage of being able to use POD types in unions.

]]>
By: TomP/2011/05/13/trivial-constructors-and-destructors-in-cpp/#comment-4229 TomP Mon, 16 May 2011 23:56:44 +0000 Really interesting post! Thanks! :) Really interesting post! Thanks! :)

]]>
By: snake5/2011/05/13/trivial-constructors-and-destructors-in-cpp/#comment-4019 snake5 Sat, 14 May 2011 10:43:00 +0000 std::vector basically calls operator new T[] internally, which in turn calls the default constructor of T() on each element -- it doesn't matter if T is an <code>int</code>, or if T is a <code>Vector</code>. Since the constructor for the <code>Vector</code> class I described is trivial, and the class is a POD type, doing an <code>new Vector[1000]</code> is effectively identical to calling <code>malloc(1000 * sizeof(Vector))</code> since no initialization needs to be performed on the class after it's been allocated. There is no undefined behavior, it is simply accepted that any memory you allocate should be set to something before you make use of it. std::vector basically calls operator new T[] internally, which in turn calls the default constructor of T() on each element — it doesn’t matter if T is an int, or if T is a Vector.

Since the constructor for the Vector class I described is trivial, and the class is a POD type, doing an new Vector[1000] is effectively identical to calling malloc(1000 * sizeof(Vector)) since no initialization needs to be performed on the class after it’s been allocated. There is no undefined behavior, it is simply accepted that any memory you allocate should be set to something before you make use of it.

]]>
By: adrien/2011/05/13/trivial-constructors-and-destructors-in-cpp/#comment-4017 adrien Sat, 14 May 2011 09:49:08 +0000 True, it is more of a stylistic thing. Either you have a function or you have a class with a single member function. Please note if you don't want the function cluttering up any namespaces make it a static member function of <code>Vector</code>. Given the choice I tend to choose Functional over Object Oriented Programming which is why I would use a function. One of the reasons I like C++ so much is that it doesn't force you into one paradigm or another. Thanks for the post. I would also be interested in reading more about code size issues. In the programming I have done in the past it has never been an issue so I would be interested in finding out more about it. True, it is more of a stylistic thing. Either you have a function or you have a class with a single member function. Please note if you don’t want the function cluttering up any namespaces make it a static member function of Vector. Given the choice I tend to choose Functional over Object Oriented Programming which is why I would use a function. One of the reasons I like C++ so much is that it doesn’t force you into one paradigm or another.

Thanks for the post. I would also be interested in reading more about code size issues. In the programming I have done in the past it has never been an issue so I would be interested in finding out more about it.

]]>
By: Michael Tedder/2011/05/13/trivial-constructors-and-destructors-in-cpp/#comment-4012 Michael Tedder Fri, 13 May 2011 21:04:23 +0000 Thanks, I'm happy I was able to help out! Thanks, I’m happy I was able to help out!

]]>
By: Michael Tedder/2011/05/13/trivial-constructors-and-destructors-in-cpp/#comment-4010 Michael Tedder Fri, 13 May 2011 20:53:46 +0000 Yeah, the code isn't a direct copy/paste, but more or less intended to give an example of what can be done. The real code is actually a bit more convoluted than that. :) Yeah, the code isn’t a direct copy/paste, but more or less intended to give an example of what can be done. The real code is actually a bit more convoluted than that. :)

]]>
By: Michael Tedder/2011/05/13/trivial-constructors-and-destructors-in-cpp/#comment-4008 Michael Tedder Fri, 13 May 2011 20:41:24 +0000 Code size is a major issue when you're trying to limit yourself to various .exe sizes (I've done a music replayer [with music] in 28k, and a game in 96k before), so this is certainly a topic I can cover in future articles. Thanks for the idea! :) Code size is a major issue when you’re trying to limit yourself to various .exe sizes (I’ve done a music replayer [with music] in 28k, and a game in 96k before), so this is certainly a topic I can cover in future articles.

Thanks for the idea! :)

]]>
By: Michael Tedder/2011/05/13/trivial-constructors-and-destructors-in-cpp/#comment-4006 Michael Tedder Fri, 13 May 2011 20:25:03 +0000 I'll be honest -- the code isn't copy/pasted directly, it was more or less given as an example for what can be achieved with unions. In any case, I'll be sure to be more careful when quoting code blocks in future posts. I’ll be honest — the code isn’t copy/pasted directly, it was more or less given as an example for what can be achieved with unions. In any case, I’ll be sure to be more careful when quoting code blocks in future posts.

]]>
By: Michael Tedder/2011/05/13/trivial-constructors-and-destructors-in-cpp/#comment-4003 Michael Tedder Fri, 13 May 2011 20:11:49 +0000 snake5 beat me to it, but yes, the order of variable initialization is exactly the same as the order of the declaration of the members in the type. snake5 beat me to it, but yes, the order of variable initialization is exactly the same as the order of the declaration of the members in the type.

]]>
By: Michael Tedder/2011/05/13/trivial-constructors-and-destructors-in-cpp/#comment-4001 Michael Tedder Fri, 13 May 2011 20:07:23 +0000 Yes, that's correct. However defining any constructor (even just to make it private) makes the class non-trivial, so the compiler no longer considers it as POD. But if you're creating an object factory, you're most likely not going to care if your class is POD or not. :) Yes, that’s correct. However defining any constructor (even just to make it private) makes the class non-trivial, so the compiler no longer considers it as POD.

But if you’re creating an object factory, you’re most likely not going to care if your class is POD or not. :)

]]>
By: Michael Tedder/2011/05/13/trivial-constructors-and-destructors-in-cpp/#comment-3999 Michael Tedder Fri, 13 May 2011 19:57:51 +0000 Have you actually inspected the assembly or profiled the code to see if empty constructors waste time? You say compilers might miss the optimization, but then progress to changing your design without any numbers to back up the hypothesis. If you have run tests, which compilers at which settings did you use? Have you actually inspected the assembly or profiled the code to see if empty constructors waste time? You say compilers might miss the optimization, but then progress to changing your design without any numbers to back up the hypothesis. If you have run tests, which compilers at which settings did you use?

]]>
By: Ron/2011/05/13/trivial-constructors-and-destructors-in-cpp/#comment-3996 Ron Fri, 13 May 2011 17:52:07 +0000 nice post. Obligatory pendantry: 'a generated constructor is responsible for calling the constructors for any derived classes' - should refer to base classes nice post.

Obligatory pendantry: ‘a generated constructor is responsible for calling the constructors for any derived classes’ – should refer to base classes

]]>
By: snake5/2011/05/13/trivial-constructors-and-destructors-in-cpp/#comment-3994 snake5 Fri, 13 May 2011 16:45:10 +0000 You shouldn’t assume that just because someone knows bitwise operations, he also knows all of the possible uses of them, for example. I wasn’t also familiar with this one just because I never needed to get a constructable POD type. So I think it’s good to have such posts, even if they seem “basic”. :)

]]>
By: adrien/2011/05/13/trivial-constructors-and-destructors-in-cpp/#comment-3991 adrien Fri, 13 May 2011 15:36:38 +0000 I don't think he mentioned having fully portable code; which is a rabbit-hole in and of itself. Both gcc and the visual studio compiler offer extensions which support this by the way... Cool post, I just love the little things that build up to make c++ the complex beast that it is (for better or worse), congrats on a nicely formed first post! I don’t think he mentioned having fully portable code; which is a rabbit-hole in and of itself.

Both gcc and the visual studio compiler offer extensions which support this by the way…

Cool post, I just love the little things that build up to make c++ the complex beast that it is (for better or worse), congrats on a nicely formed first post!

]]>
By: Fabrice Lété/2011/05/13/trivial-constructors-and-destructors-in-cpp/#comment-3987 Fabrice Lété Fri, 13 May 2011 14:08:28 +0000 Your "active working example" is illegal according to the standard. 9.5.2 "A union of the form union { member-specification } ;is called an anonymous union; it defines an unnamed object of unnamed type. The member-specification of an anonymous union shall only define non-static data members. [Note: nested types and functions cannot be declared within an anonymous union. ] " Your “active working example” is illegal according to the standard.

9.5.2
“A union of the form union { member-specification } ;is called an anonymous union; it defines an unnamed object of unnamed type. The member-specification of an anonymous union shall only define non-static data members. [Note: nested types and functions cannot be declared within an anonymous union. ] “

]]>
By: João Matos (triton)/2011/05/13/trivial-constructors-and-destructors-in-cpp/#comment-3982 João Matos (triton) Fri, 13 May 2011 12:24:08 +0000 Do you ever take advantage of VectorC as a type? Or could you instead get away with using a function like the following? <code> Vector v(float x, float y, float z) { Vector v; v.x = x; v.y = y; v.z = z; return v; } </code> I just find myself writing lots of these little helper functions. They are especially useful for working with type inference. So you could overload <code>v()</code> to work with multiple types. Then you do something like: <code> template void f(value_t x, value_t y, value_t z) { ... = v(x, y, z); } </code> In the above <code>v()</code> can be defined return the right type for float, double, bool or whatever you want. Do you ever take advantage of VectorC as a type? Or could you instead get away with using a function like the following?


Vector v(float x, float y, float z) { Vector v; v.x = x; v.y = y; v.z = z; return v; }

I just find myself writing lots of these little helper functions. They are especially useful for working with type inference. So you could overload v() to work with multiple types. Then you do something like:


template
void f(value_t x, value_t y, value_t z)
{
... = v(x, y, z);
}

In the above v() can be defined return the right type for float, double, bool or whatever you want.

]]>
By: Lee Winder/2011/05/13/trivial-constructors-and-destructors-in-cpp/#comment-3977 Lee Winder Fri, 13 May 2011 10:59:03 +0000 Good post. Not the focus, but I hope you dont actually have two bools in your Transform struct if you're worried about preserving memory. Good post. Not the focus, but I hope you dont actually have two bools in your Transform struct if you’re worried about preserving memory.

]]>
By: john/2011/05/13/trivial-constructors-and-destructors-in-cpp/#comment-3971 john Fri, 13 May 2011 09:53:36 +0000 Inheriting from Vector to give a constructor is genius! I've been working on this problem for a long time and I never thought of that solution. Thanks for the great post. Inheriting from Vector to give a constructor is genius! I’ve been working on this problem for a long time and I never thought of that solution.

Thanks for the great post.

]]>
By: Aurélien Pocheville/2011/05/13/trivial-constructors-and-destructors-in-cpp/#comment-3967 Aurélien Pocheville Fri, 13 May 2011 08:42:28 +0000