I narrowed down the source of the error. The stand-alone program
listed
below reproduces it. The compilation finishes but the warning is
too serious to ignore:
cl -GX prog.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for
80x86
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.
prog.cpp
prog.cpp(18) : warning C4172: returning address of local variable or
temporary
Microsoft (R) Incremental Linker Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
/out:prog.exe
prog.obj
The line it refers to is in Matrix class definition:
const_reference operator()(size_type m, size_type n) const
{return array[m*ncol + n];}
The typedefs involved are
typedef double value_type;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef size_t size_type;
and array is of valarray type.
The array is a member of the Matrix class, so an element of it
should not be a temporary or a local variable, it seems to me.
Is this diagnostic correct? (Please see bottom of message for the
rest of the code.)
When I ran the program, the matrix it printed was
1 4.04
1 4.04
and the correct answer, given by the g++ compiled version, is
275 -495
275 -495
If anybody still has vc++ Version 6.0, I would appreciate
confirmation or denial that the compiler does what I said
above, by compiling and running the single-file program
below. It may be an installation or library problem I am
having. Should the standard library used by vc++ be updated
separately or do the patches issued by MS cover all there is
to cover (I have applied SP5 for Visual Studio)?
Thanks,
Levent
#include <iostream>
#include <cmath>
#include <valarray>
class Matrix
{
public:
typedef double value_type;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef size_t size_type;
Matrix() :nrow(0), ncol(0) {}
Matrix(size_type m, size_type n) : nrow(m), ncol(n)
{array.resize(m*n, 0);}
size_type rowsize() const {return nrow;}
size_type colsize() const {return ncol;}
reference operator()(size_type m, size_type n) {return array[m*ncol
+ n];}
const_reference operator()(size_type m, size_type n) const {return
array[m*ncol + n];}
std::valarray<value_type> array;
Matrix & operator=(const Matrix & B)
{
if (&B != this)
{
nrow = B.rowsize();
ncol = B.colsize();
array.resize(nrow*ncol);
array = B.array;
}
return *this;
}
friend void print(const Matrix& A)
{
size_t m, n;
for (m = 0; m < A.nrow; ++m)
{
for (n = 0; n < A.ncol; ++n)
std::cerr << " " << A(m, n);
std::cerr << '\n';
}
}
private:
size_type nrow, ncol;
};
Matrix operator*(const Matrix & A, const Matrix & B)
{
size_t m = A.rowsize(), p = A.colsize(), n = B.colsize(), i, j, k;
Matrix C(m, n);
for (i = 0; i < m; ++i)
for (j = 0; j < n; ++j)
for (k = 0; k < p; ++k)
C(i, j) += A(i, k)*B(k, j);
return C;
}
int main ()
{
Matrix M(2, 2);
Matrix N(2, 2), P(2, 2);
M.array = 275;
N(0, 0) = 1;
N(0, 1) = -2;
N(1, 0) = 0;
N(1, 1) = 1.0/5.0;
P = M*N;
print(P);
return 0;
} |