Sign in to follow this  
ProPuke

References... are real

Recommended Posts

ProPuke    466
I've kinda presumed upto now that references would be optimised out by my good old friend gcc, but he seems to be compiling them in. I'm wondering: Why it is references actually take up space when compiled & optimised. I mean surely the compiler should just be able to link to the object it references directly rather than using the equivilent of a pointer to store the address all the time? For instance I thought the following would be a rather good idea:
struct Vector{
  /**/ Vector():
    x(data[0]),y(data[1]),z(data[2]),
    r(data[0]),g(data[1]),b(data[2])
  {data[0]=0;data[1]=0;data[2]=0;}

  float data[3];
  float &x,&y,&z;
  float &r,&g,&b;
};
typedef Vector Colour;
"There we go..." I thought to myself ".. Less code, more pleasing to my eye, & no extra size :]" sizeof(Vector)==36[bawling] Even under full optimisation :( I presumed c++ would treat it kinda like a macro for the target but it appears I was wrong. Can anyone expand on why it is neccasary to store the address? & if they, too, have hit the same thing, & what they chose to do instead? All thoughts appreciated :]

Share this post


Link to post
Share on other sites
nmi    978
Your compiler might look at the structure like this:


struct Vector{
Vector(); // a constructor
float data[3];
float &x,&y,&z;
float &r,&g,&b;
};


At this time, the size of the struct must be calculated, e.g. if you put it inside another class:


class A {
Vector vec;
};


So every reference has space reserved with the size of a pointer.

The implementation for Vector::Vector() might be in a .cpp file, not seen by class A.



Why don't you write:

struct Vector
{
union {
float data[3];
struct { float x, y, z; };
struct { float r, g, b; };
};
};

Share this post


Link to post
Share on other sites
snk_kid    1312
There is no way any compiler will even attempt to optimize it, the usual time reference types may be optimized away is with function parameters in trivial use cases.

Also you can't use user-defined constructors if you use unions with arrays, if you want to construct the elements & have array type access you can use a static constant pointer to data members e.g.:


struct Vector3 {

typedef size_t size_type;

private:

typedef float Vector3::* const vec[3];

static const vec v;

public:

float x, y, z;

Vector4(float nx = 0.0f, float ny = 0.0f, float nz = 0.0f)
: x(nx), y(ny), z(nz) {}

const float& operator[](size_type i) const {
return this->*v[i];
}

float& operator[](size_type i) {
return this->*v[i];
}

};

const Vector3::vec Vector3::v = { &Vector3::x, &Vector3::y, &Vector3::z };


if you want to see some more pointer to data memeber tricks refer to this

Quote:
Original post by nmi
Why don't you write:

struct Vector
{
union {
float data[3];
struct { float x, y, z; };
struct { float r, g, b; };
};
};


Because anonymous structures are non standard compliant, its a compiler extension, not portable.

[Edited by - snk_kid on February 15, 2005 4:17:03 PM]

Share this post


Link to post
Share on other sites
JohnBolton    1372
The references can't be optimized away because their values are determined at run-time. For example, what if you have two constructors and they initialize the references differently.

Share this post


Link to post
Share on other sites
snk_kid    1312
Quote:
Original post by Extrarius
There is a solution to this exact problem (vectors with .x AND [0]) on these forums somewhere, but I can't find the thread.



struct vector3 {

float x, y, z;
...
float& operator[](size_t i) {
return (&x)[i];
}
....
};


my original version is safer, standard compliant, and will can be easily optimized (proven in another thread).

Share this post


Link to post
Share on other sites
ProPuke    466
Thanks for the feedback *adjusts television set*

Quote:
what if you have two constructors and they initialize the references differently
Dang, good point

snk_kid: Thanks, but as simple & perfect as that solution is it still only uses 1 set of names for accessing the members (xyz)

when _the_phantom_ mentioned unions (something I don't use them alot @ all)...
union{
float data[3];
struct{float x,y,z;};
struct{float r,g,z;};
};
...popped into my head aswell - just like nmi said.
Okay it might not be offical golden standards, but aren't gcc standards enough?

Any thoughts as to implementing this according to standards?

Share this post


Link to post
Share on other sites
Extrarius    1412
Quote:
Original post by snk_kid
[...]my original version is safer, standard compliant, and will can be easily optimized (proven in another thread).
Actually, your solution is the one I was talking about. I clicked reply before you posted, but didn't actually post until after =-/

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this