Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   reinterpret_cast<> and UB (http://www.velocityreviews.com/forums/t456721-reinterpret_cast-and-ub.html)

 Nate Barney 09-07-2006 05:37 PM

reinterpret_cast<> and UB

I have:

// base class for Vector and Matrix
template <unsigned N,typename Value=float>
class NonScalar
{
public:

Value *ptr() { return e; }
const Value *ptr() const { return e; }

private:

Value e[N];
};

// Vector class
template <unsigned N,typename Value=float>
class Vector : public NonScalar<N,Value>
{
public:

Vector() {}
Vector(const NonScalar<N,Value> &ns) : NonScalar<N,Value>(ns) {}
};

// Matrix class
template <unsigned R,unsigned C,typename Value=float>
class Matrix : public NonScalar<R * C,Value>
{
public:

Matrix() {}
Matrix(const NonScalar<R * C,Value> &ns) : NonScalar<R *
C,Value>(ns) {}

// Matrix multiplication operator
template <unsigned N>
Matrix<R,N,Value> operator*(const Matrix<C,N,Value> &m) const;
}

// Matrix * Vector operator
template <unsigned R,unsigned C,typename Value>
inline Vector<R,Value> operator*(const Matrix<R,C,Value> &m,
const Vector<C,Value> &v)
{
return static_cast<const Vector<R,Value>&>(m *
static_cast<const Matrix<C,1,Value>&>(v));
}

// Vector * Matrix operator
template <unsigned R,unsigned C,typename Value>
inline Vector<C,Value> operator*(const Vector<R,Value> &v,
const Matrix<R,C,Value> &m)
{
return static_cast<const Vector<C,Value>&>(
static_cast<const Matrix<1,R,Value>&>(v) * m);
}

The v*m and m*v operators work correctly, but the second static_cast<>
in each one copies the contents of the Vector into a temporary Matrix,
via the NonScalar copy constructor. What I'd like to do is replace
this cast with a reinterpret_cast<>, which would simply treat the
Vector like a Matrix for the purposes of the call. The question is:
would doing so invoke undefined behavior? If so, is there a way to
make these operators work without copying their contents?

Thanks,
Nate

 Nate Barney 09-07-2006 05:41 PM

Re: reinterpret_cast<> and UB

Nate Barney wrote:
>
> // Matrix class
> template <unsigned R,unsigned C,typename Value=float>
> class Matrix : public NonScalar<R * C,Value>
> {
> /* snip */
> }

Oops, forgot the semicolon here.

 Ron Natalie 09-08-2006 11:34 AM

Re: reinterpret_cast<> and UB

Nate Barney wrote:

>
> The v*m and m*v operators work correctly, but the second static_cast<>
> in each one copies the contents of the Vector into a temporary Matrix,
> via the NonScalar copy constructor. What I'd like to do is replace
> this cast with a reinterpret_cast<>, which would simply treat the
> Vector like a Matrix for the purposes of the call. The question is:
> would doing so invoke undefined behavior? If so, is there a way to
> make these operators work without copying their contents?
>

No. The fact that the two classes are derived from a common base
and there are no virtual functions in play or data members in the
derived class indicate it might work, the standard doesn't require
it.

What I might do to accomplish this is provide a Matrix class
(or a Matrix-like) class that is initialized with a Vector
and gets at the underlying NonScalar by reference rather than
making a copy.

 Nate Barney 09-08-2006 03:25 PM

Re: reinterpret_cast<> and UB

Ron Natalie wrote:
>
> No. The fact that the two classes are derived from a common base
> and there are no virtual functions in play or data members in the
> derived class indicate it might work, the standard doesn't require
> it.

That's what I was afraid of. Oh well. Thanks for clearing that up for
me.

> What I might do to accomplish this is provide a Matrix class
> (or a Matrix-like) class that is initialized with a Vector
> and gets at the underlying NonScalar by reference rather than
> making a copy.