Compilation and runtime error with vc++ Version 6.0

C

Count Dracula

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;
}
 
T

tom_usenet

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];}

Change that to:

value_type 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.

However, valarray::eek:perator[] const returns a temporary object by
value. This is considered a defect in the standard:
http://std.dkuug.dk/jtc1/sc22/wg21/docs/lwg-active.html#389

The change above is the only reasonable portable solution until the
defect goes through.

Tom
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top