// { dg-do run } // GROUPS passed code-generation // code-gen file // From: "David" // Date: Mon, 15 Nov 1993 20:59:14 -0600 (CST) // Subject: An error! // Message-ID: <9311160259.AA03353@pi14.arc.umn.edu> #include #include #include #include #include #include #define ANSI_C typedef double VEC ; class Vector; class VectorInt { public: /* Nothing public!! Only Vector can use this class */ private: VectorInt( int ); VectorInt( int, double *, int = 0 ); VectorInt( const VectorInt & ); ~VectorInt(); VectorInt *refer(); void unrefer(); int count; /* Number of Vector's referring to me */ VEC *vec; friend class Vector; friend class VecElem; }; class VecElem { public: operator double(); double operator=( double ); private: VecElem( Vector &, int ); VecElem( const VecElem & ); Vector &v; int row; /* Row element refers to */ friend class Vector; }; class Vector { public: Vector(); // Must be assigned to before used Vector( VectorInt * ); Vector( int ); Vector( int, double *, int beg = 0 ); Vector( const Vector & ); Vector &operator=( const Vector & ); ~Vector() { if(r) r->unrefer(); } int row() const { return 19; } int dim() const { return 10; } double operator()( int ) const; VecElem operator()( int ); double assign( int, double ); friend std::ostream& operator<<(std::ostream&, const Vector& m ); private: VectorInt *r; /* Reference to real data */ friend class VecElem; friend class LUDecom; friend class SVD; }; Vector:: Vector() : r(0) {} Vector:: Vector( VectorInt *vi ) : r(vi) { r->refer(); } Vector:: Vector( int row ) { assert( row > 0 ); r = new VectorInt( row ); r->refer(); } Vector:: Vector( int row, double *d, int beg ) { assert( row > 0 ); r = new VectorInt( row, d, beg ); r->refer(); } Vector:: Vector( const Vector &A ) : r( A.r->refer() ) {} Vector& Vector:: operator=( const Vector &A ) { if( r ) r->unrefer(); r = A.r->refer(); return *this; } double Vector:: operator()( int row ) const { assert(r != 0); return *r->vec; } VecElem Vector:: operator()( int r ) { assert(r != 0); return VecElem( *this, r ); } /* assign changes the matrix, it does not create a new one! */ double Vector:: assign( int rownum, double d ) { assert(r != 0); if( rownum > row() || rownum <= 0 ) { std::cerr << "Warning: trying to assign out of bounds" << std::endl; std::cerr << "row " << rownum << std::endl; std::cerr << "Vector size " << row() << std::endl; std::abort(); } if( r->count == 1 ) { /* Don't need to create a new matrix, since we are the only */ /* one pointing to ours */ } else { VectorInt *vi = new VectorInt( *r ); r->unrefer(); r = vi->refer(); } return d; } VectorInt:: VectorInt( int sx ) : vec( new double[sx] ), count(0) { } VectorInt:: VectorInt( int sx, double *, int ) : vec( new double[sx] ), count(0) { } VectorInt:: VectorInt( const VectorInt & ) : vec( new double[10] ), count(0) { } VectorInt * VectorInt:: refer() { count ++; return this; // cout << "Refering vec" << endl; } void VectorInt:: unrefer() { count--; if( count == 0 ) { delete this; } // cout << "Unrefering vec" << endl; } VectorInt:: ~VectorInt() { delete vec; vec = 0; } VecElem:: VecElem( Vector &vec, int r ) : v(vec), row(r) { if( r < 1 || r > vec.row() ) { std::cerr << "Trying to access vector element out of bounds"; std::cerr << std::endl; std::abort(); } } VecElem:: VecElem( const VecElem &elem ) : v(elem.v), row(elem.row) {} VecElem:: operator double() { assert( v.r->vec != 0 ); return *v.r->vec; } double VecElem:: operator=( double d ) { return v.assign( row, d ); } int makeforms( Vector cen, Vector **a, Vector **b ); int main() { Vector *a[8], *b[8], disp(3); Vector cen(3), cen2(3); int i, j; if (makeforms (cen,a,b) != 10) { std::printf ("FAIL\n"); return 1; } else std::printf ("PASS\n"); } int makeforms( Vector cen, Vector **a, Vector **b) { return 10; }