Jump to content
  • Advertisement
Sign in to follow this  
JoshuaWaring

Location of data in the class

This topic is 1578 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

when I define a class with only these variables

float _m11, _m12, _m13;
float _m21, _m22, _m23;
float _m31, _m32, _m33;

is it safe to assume that to access _m13 from the pointer of _m11 I can

(&_m11)[2]

and 

to get to _m21

(&_m11)[3]

to my understanding this should be allowed, but I was wondering if it'll always be placed in RAM like this or some systems might shuffle them for a reason I don't know.

Share this post


Link to post
Share on other sites
Advertisement

I was also curious if the same could be said for functions arguments, 

Vector4(float _x, float _y, float _z, float _w);

Would all these be in the same order and sequential?

 

Thank you for any help, it would be much appreciated.

Share this post


Link to post
Share on other sites

As mentioned above, it is not safe due to possible padding between members. You can however use a nameless struct here to achieve the same effect,

class matrix {
public:
 
   union {
        float m[9];
      struct {
         float _m11, _m12, _m13;
         float _m21, _m22, _m23;
         float _m31, _m32, _m33;
      };
   };
 
// now m[1] = _m11, m[2] = _m12 etc.
};

It is important to note that nameless structures are not standard although a few modern compilers support it.

Edited by Crypter

Share this post


Link to post
Share on other sites

I've seen this used before in a graphics rendering library.

 

The compiler does not reorder any members, and I assume there would be no padding, because 32-bit floats align correctly in 32-bit and 64-bit addressable memory, but it's not written in stone - the compiler is allowed to add padding if it wants to.

Edited by TheComet

Share this post


Link to post
Share on other sites

Not what I wanted to hear, but thank you anyway :3

there's no way to ensure no padding is there? 

guess it's back to my  float _m[3][3] then

Share this post


Link to post
Share on other sites

The compiler does not reorder any members, and I assume there would be no padding, because 32-bit floats align correctly in 32-bit and 64-bit addressable memory, but it's not written in stone - the compiler is allowed to add padding if it wants to.


I think assuming that is not unhealthy. I'm not in the habit of hand-rolling my matrix libraries but I would probably assume no padding and then
static_assert(sizeof(matrix) == 9 * sizeof(float), "This platform does not deal well with padding; must be handled explicitely");

Share this post


Link to post
Share on other sites

Not what I wanted to hear, but thank you anyway :3

there's no way to ensure no padding is there? 

guess it's back to my  float _m[3][3] then

Technically you can enforce a specific alignment or none at all via compiler specific #pragma options. For example, in MSVC, #pragma pack directive or G++ attribute((packed)). TheComet is correct though, floats are very well standardized and guaranteed to be 32 bits so it is most probably safe to assume proper dword alignment without padding. The only guaranteed methods however would be compiler dependent; that is, resulting to nameless structures or #pragma.

 

You can also just overload operator[] and call it directly.
 

Alternatively just don't do it. You are not gaining anything from doing this after all. It can be done, of course, but at what benefit?

Edited by Crypter

Share this post


Link to post
Share on other sites

Not what I wanted to hear, but thank you anyway :3

there's no way to ensure no padding is there? 

guess it's back to my  float _m[3][3] then

Using these kind of trick, will work but it is also how you write unmaintainable code. And code readability is often more important than ease of writing your code, because in six months time you are going to be wondering why you wrote it that way.

 

The other way of doing this is

class Matrix44
{
private:
    union
    {
        float f[16];
        float mm[4][4];
        Vector4  v[4]; //Assuming vector4 is stored as 128 bytes contiguously
    } matrix;
}

You can now access matrix.f as an array, matrix.mm as a 2D array or as an array of vector4, if you add 16 float variables in the union you get 16 slot access options.

Edited by NightCreature83

Share this post


Link to post
Share on other sites
Washu posted a very neat implementation here: http://www.gamedev.net/topic/391237-criticize-my-custom-vector-class/page-5#entry3598509
 
struct Vector3 {
  float x, y, z;
  
  float &operator[](int index) {
    assert(index >= 0 && index < 3);
    return this->*members[index];
  }

  float operator[](int index) const {
    assert(index >= 0 && index < 3);
    return this->*members[index];
  }

  static float Vector3::* const members[3];
};

float Vector3::* const Vector3::members[3] = { &Vector3::x, &Vector3::y, &Vector3::z};
Edited by Álvaro

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!