Vector3 member initialization
-
Peet
- Gnoblar
- Posts: 3
- Joined: Thu Nov 25, 2010 1:21 am
Vector3 member initialization
Personally, when I call the default constructor of a class, I make the assumption that that class' members are now initialized to a sane non-NaN value. I believe this places me in same category as the general programming public - it strikes me a pretty reasonable assumption. Similarly, the Ogre coding guidelines state All class variables should be initialized to a sane value in the constructor.
So why is the Vector3 class a blatant exception to this? People in #ogre3d have been making the argument that leaving initialization to the users of the library has a performance advantage, but the constructor is inline which means any resultant multiple assignments will be optimized out by any sane compiler. Even if that were a valid argument, the complete lack of documentation of this fact makes it a very notable pitfall for developers using Ogre.
So why is the Vector3 class a blatant exception to this? People in #ogre3d have been making the argument that leaving initialization to the users of the library has a performance advantage, but the constructor is inline which means any resultant multiple assignments will be optimized out by any sane compiler. Even if that were a valid argument, the complete lack of documentation of this fact makes it a very notable pitfall for developers using Ogre.
-
dark_sylinc
- OGRE Team Member

- Posts: 5586
- Joined: Sat Jul 21, 2007 4:55 pm
- Location: Buenos Aires, Argentina
- x 1413
Re: Vector3 member initialization
No.Peet wrote:People in #ogre3d have been making the argument that leaving initialization to the users of the library has a performance advantage, but the constructor is inline which means any resultant multiple assignments will be optimized out by any sane compiler.
Anything where the initialization is obfuscated, may not get inlined and initialization can't be optimized out.
Consider this simple DLL example:
Code: Select all
__declspec(dllexport) Ogre::Vector3 returnMyVector() { return Ogre::Vector3(); }Furthermore, floating point optimizations are much less aggressive than one would think, compared to integer optimizations or any other kind (which is so, in order to preserve precision). Even obvious optimizations like a = a / 2.0f may not be optimized to a = a * 0.5f because in floating point, this isn't actually the same.
Fair point. Advanced users of 3D graphic engines assume that things like Vectors and Quaternions aren't usually initialized (the latter is initialized in Ogre); so we forget programmers new into 3D programming don't know this.Peet wrote:Even if that were a valid argument, the complete lack of documentation of this fact makes it a very notable pitfall for developers using Ogre.
-
Peet
- Gnoblar
- Posts: 3
- Joined: Thu Nov 25, 2010 1:21 am
Re: Vector3 member initialization
This is a bit of a ridiculous argument...If the constructor of Vector3 is called inside the ogre so/dll from the game (tip: it's not), 3 additional assignments are not the primary optimization concern heredark_sylinc wrote:No.Peet wrote:People in #ogre3d have been making the argument that leaving initialization to the users of the library has a performance advantage, but the constructor is inline which means any resultant multiple assignments will be optimized out by any sane compiler.
Anything where the initialization is obfuscated, may not get inlined and initialization can't be optimized out.
Consider this simple DLL example:When this function gets called from an exe to the dll, the compiler has no way to know at compile time what happens to the returned values or what is being returned. There's little chance of optimization.Code: Select all
__declspec(dllexport) Ogre::Vector3 returnMyVector() { return Ogre::Vector3(); }
How is this even relevant? Only assignment is in question here; mentioning other operations is just a red herring....dark_sylinc wrote:Furthermore, floating point optimizations are much less aggressive than one would think, compared to integer optimizations or any other kind (which is so, in order to preserve precision). Even obvious optimizations like a = a / 2.0f may not be optimized to a = a * 0.5f because in floating point, this isn't actually the same.
Telling me that a similar class DOES initialize its members doesn't exactly strengthen your justification for not initializing a vector in its default ctor. This sort of inconsistency doesn't only affect "programmers new into 3D programming", and I would definitely appreciate it if you would not assume that someone whose views do not match your own is inexperienced.dark_sylinc wrote:Advanced users of 3D graphic engines assume that things like Vectors and Quaternions aren't usually initialized (the latter is initialized in Ogre); so we forget programmers new into 3D programming don't know this.
-
jacmoe
- OGRE Retired Moderator

- Posts: 20570
- Joined: Thu Jan 22, 2004 10:13 am
- Location: Denmark
- x 179
Re: Vector3 member initialization
The difference is probably that Vector3 is meant to be treated like a primitive type.
Just like int, float, etc.
Just like int, float, etc.
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
-
so0os
- Bugbear
- Posts: 833
- Joined: Thu Apr 15, 2010 7:42 am
- Location: Poznan, Poland
- x 33
Re: Vector3 member initialization
Does float get initialised whgen you declare it? What's the point?!?! if you need a vector, i think you want to use it, and if you do you get a warning.
-
Peet
- Gnoblar
- Posts: 3
- Joined: Thu Nov 25, 2010 1:21 am
Re: Vector3 member initialization
This is sensible; all I ask is that it be noted in the doxygen documentation.jacmoe wrote:The difference is probably that Vector3 is meant to be treated like a primitive type.
Just like int, float, etc.
Vector3 is a class, not a built in type. Arguing implicitly that it is to be treated like a primitive type is not valid (and there is no warning that a Vector3 is uninitialized since it just calls the empty default constructor).so0os wrote:Does float get initialised whgen you declare it? What's the point?!?! if you need a vector, i think you want to use it, and if you do you get a warning.
-
dark_sylinc
- OGRE Team Member

- Posts: 5586
- Joined: Sat Jul 21, 2007 4:55 pm
- Location: Buenos Aires, Argentina
- x 1413
Re: Vector3 member initialization
It was an example. It extends to any DLL function that returns Vector3, any Vector3 initialized in the exe but passed to the DLL, or any function that accepts a reference or pointer as an argument.Peet wrote:This is a bit of a ridiculous argument...If the constructor of Vector3 is called inside the ogre so/dll from the game (tip: it's not), 3 additional assignments are not the primary optimization concern here
By the way, it's not just "3 additional assignments". It's 3 additional assignments per Vector3 declaration (there are too many) per frame. And half or more of them won't be optimized away sadly.
Again, an example. If the compiler can't be guaranteed the value is uninitialized, it has to shift some bits of instruction in some situations to adjust to this. It holds more important when passing a (const or not) reference, than when passing by copy.Peet wrote:How is this even relevant? Only assignment is in question here; mentioning other operations is just a red herring....
I chose carefully my words when phrasing it, so that it would be clear that I didn't say "inexperience programmer". Even the most experienced of programmers can't know what are the common uses and traditions in a certain field, this case 3D graphics; until he gets fond with it.Peet wrote:This sort of inconsistency doesn't only affect "programmers new into 3D programming", and I would definitely appreciate it if you would not assume that someone whose views do not match your own is inexperienced.
jacmoe & so0os are right in that the intention is to treat Vector2/Vector3/Vector4 as a data type, maintaining consistency with GPU architectures (shaders); where vectorN is a native data type.
But you're right the documentation could and should be more explicit about this. And certainly doesn't hurt adding it.
By the way there's no default "correct" initialization of a Vector3, because it depends on the intention. When you're working with scales, the "most valid" initialization is Ogre::Vector3::UNIT_SCALE, when you're working with rotations/quaternions the valid initialization is either UNIT_X/UNIT_Y/UNIT_Z or their negative counterparts.
Forcing these explicit initializations helps visualizing the intention and usage of math code. And these initializations are probably more common and used throughout the whole engine than setting everything to zeros.
Cheers
Dark Sylinc
-
sparkprime
- Ogre Magi
- Posts: 1137
- Joined: Mon May 07, 2007 3:43 am
- Location: Ossining, New York
- x 13
Re: Vector3 member initialization
It's not actually that uncommon to have a class type that is not fully initialised upon construction. Not preferable, either, of course. I think the style guides need updating and better documentation. Personally I figured it out by reading the source code, which is what I always do when the documentation is unclear.
-
kneeride
- Bugbear
- Posts: 807
- Joined: Sun May 14, 2006 2:24 pm
- Location: Melbourne, Australia
Re: Vector3 member initialization
Hi guys, this topic has come up a number of times. I couldn't find the post but sinbad once said that that this decision was based on performance. Somewhere in the code is a an array of vectors and removing the initialisation improved performance significantly (I assume by avoiding construction on multiple objects). Sinbad had played around with both ideas and decided on handling vectors as a primative type for this reason. Sorry but I couldnt find the post.
-
jbb
- Gnoblar
- Posts: 15
- Joined: Sun Nov 07, 2004 12:53 pm
- x 1
Re: Vector3 member initialization
Also, the compiler is often able to warn you that you are reading an uninitialised variable - and tools like purify certainly will.
If you initialise it to anything else, it's almost certainly not the correct value, but you've lost the ability of your tools to warn you about it.
If you initialise it to anything else, it's almost certainly not the correct value, but you've lost the ability of your tools to warn you about it.
-
dark_sylinc
- OGRE Team Member

- Posts: 5586
- Joined: Sat Jul 21, 2007 4:55 pm
- Location: Buenos Aires, Argentina
- x 1413
Re: Vector3 member initialization
Ahhh yes. I'm not familiar with the original thread, but it gives one of the many examples involving trivial STL operation, in which code can't be optimized by a compiler:kneeride wrote:Hi guys, this topic has come up a number of times. I couldn't find the post but sinbad once said that that this decision was based on performance. Somewhere in the code is a an array of vectors and removing the initialisation improved performance significantly (I assume by avoiding construction on multiple objects). Sinbad had played around with both ideas and decided on handling vectors as a primative type for this reason. Sorry but I couldnt find the post.
Code: Select all
std::vector<Ogre::Vector3> myArray;
myArray.resize( 1000 );Code: Select all
Ogre::Vector3 *myPtr = &myArray[123];
float x = myPtr->x; //reading uninitialized variable or...
myPtr->x = 120.0f; //...setting variables to valid values, skipping the default ones The resize is just one of many examples. Copy operations often involve constructors, which I'm guessing would be probably the biggest cause of performance slowdowns.
Furthermore Ogre has been expanding to handhelds lately, and compilers for those platforms aren't nearly as advanced as x86 compilers when it comes to optimizations.
My thoughts those guidelines applies mostly to true objects (MaterialManager, Material, Mesh, SubMesh, SceneManager) which by the way aren't initialized that often, and they should have a sane value. But Vector3 acts more as a container of floats, than rather an object IMHO.