I am creating a matrix class whose underlying operations are being performed on an external device (a high end GPU). the matrix is templated and the declaration looks something like this,

Code:
template <int nrows, int ncols, int ld = nrows>
class cmatrix 
{
public:
	float *val ; // pointer to the data on the device
/* ...  more stuff */


cmatrix &operator=(const cmatrix &rhs)
{
	
	if (this != &rhs) {

/* I do NOT delete the old val pointer and create a new one since the default copy
   constructor always allocates a 'fixed'  size block of memory */
		
	/* nasty device code that copies the stuff in rhs.val to this->val */
		

	

	}
	
return(*this)  ;
} // end operator=
} ;
I have an overloaded multiply operator that does what you'd expect. Note that it returns a cmatrix object. Un-optimized code will delete the product object, C, after copying it to the output object.

Code:
/* matrix multiplication */
template <int rows, int cols, int ld,  int cols1, int ld1>
cmatrix<rows, cols1, rows> operator*(const cmatrix<rows,cols,ld> &A, const cmatrix<cols,cols1,ld1> &B)
{
cmatrix<rows,cols1,rows> C ;
/* call device operations to move A * B into C .... */

return(C) ;

}

Now comes the strange part. Creating a matrix that is a product of two matrices can create memory errors depending on how I use the assignment operator and whether I making a debug or optimized release code. The issue is which assignment operator is called (default or templated) and how the product operator returns it's values.

This occurs on MS Visual Studio 2005, within it's debugger.
Code:
int main(int argc, char *argv[])
{
/* Init code creates 2 2 x2 matrix A and B */


/* Default constructor called for C, but template assignment operator NOT used.
Thus a memory leak and invalid memory created for C */
cmatrix<2,2>  C = A * B ;   

std::cout << C ;  // ERROR!  C has already been deleted (if using debug)


}
On the other hand if declare C first, the templated assignment operator does get used, but even stranger behavior quickly follows.

Code:
int main(int argc, char *argv[])
{
/* Init code creates 2 2 x2 matrix A and B */



cmatrix<2,2>  C  
/* temp output of A*B deleted after operator*  returns  
C  = A * B ;  // wtf?  right hand side of assignment operator deleted!,  attempting
// to delete  temp output twice, causing a call to two frees on the same pointer.

std::cout << C ;  // never  reaches this

}
So there are two mysteries here. The first is why the default assignment operator gets used in the first case, where I put the declaration and product on the same line. The second mystery is why after the assignment operator it feels the need to delete it's right hand side again!

I find this business of what the default behavior of the compiler, especially when using templates rather arcane. By the way, the release mode (optimized) code seems to run just fine. So some assignment operator optimizations actually change the semantics. Is this just an MS 'feature'?