On 7/19/07, tbp <[EMAIL PROTECTED]> wrote:
I have that usual heavy duty 3 fp components class that needs to be
reasonably efficient and takes this form for g++
struct vec_t {
float x,y,z;
const float &operator()(const uint_t i) const { return *(&x + i); }
float &operator()(const uint_t i) { return *(&x + i); } // <-- guilty
[snip ctors, operators & related cruft]
};
I use this notation because g++ does silly things with straight arrays
(and C++ gets in the way), doesn't like
union vec_t {
struct { float x,y,z; };
float f[3];
const float &operator()(const uint_t i) const { return m[i]; }
float &operator()(const uint_t i) { return m[i]; }
};
much either, and seems to enjoy the first form (+ ctors with
initializer lists) much. So far, so good.
Alas, somewhere between gcc-4.3-20070608 (ok) and gcc-4.3-20070707
(not ok ever since), the non const indexing started to trigger bogus
codegen with some skipped stores on x86-64, but of course only in
convoluted situations. So, i can't produce a simple testcase. I can
kludge around either by:
. marking it __attribute__((noinline))
. turning it into a "set" operation doing a "std::memcpy(&x + i, &f,
sizeof(float))"
. annoying the optimizer with the entertaining
union vec_t {
struct { float x,y,z; };
float f[3];
const float &operator()(const uint_t i) const { return *(&x + i); }
float &operator()(const uint_t i) { return *(&x + i); }
};
At this point i'd need some guidance from compiler developers because
the compiler itself provides none (no warning whatsoever in any of
those variations) and what i thought was acceptable apparently isn't
anymore.
What kind of idiom am i supposed to write such thing in to get back
efficient and correct code?
Well, I always used the array variant, but you should be able to do
struct vec {
...
union {
struct { float x, y, z; } a;
float x[3] b;
} u;
}
if you need to (why does the array form not work for you?)
Richard.