wim@targon.UUCP (Wim C. J. van Eerdt) (12/15/87)
Here is another file, that I have got from my colleague:
Gerard van Dorth.
When you want to contact him you can write to:
Gerard van Dorth
Nixdorf Computer BV.
Department: EG4
Postbus 29
4130 EA Vianen
The Netherlands
Voice: +31 3473 75154
E-mail: No direct contact. (I promise to forward a printed version of your
mail to him.)
Here it goes!
------------------------------------------------------------------------
Subject: Now a bug (?)
#include <stream.h>
class string {
char *s;
int n;
public:
string();
string( char* );
string( string& );
friend ostream& operator<< ( ostream&, string& );
} ;
// ...
const string text = "text";
void call()
{
cout << text; // reference to a const object.
}
A colleague typed the exhibited program and found an error on line
cout << text;
The message is correct: the 2nd argument of operator<< is a reference to a
string. So he changed the definition into
friend ostream& operator<< ( ostream&, string );
Surprise, that did not work either: the constructor string( string& ) still
takes the reference of the constant object. Neither skipping the constructor
nor skipping the cont declaration is the answer, who knows the answer.
--
Wim van Eerdt E-mail: mcvax!targon!wim
OSP, Nixdorf Computer Bv, Postbus 29, 4130 EA Vianen
Nederland. Tel.: +31 3473 62211.mikem@otc.oz (Mike Mowbray) (12/27/87)
In article <370@targon.UUCP>, Gerard van Dorth says: > A colleague typed the exhibited program and found an error on line > cout << text; Removing the const declaration of text will work, as will changing the friend function in class string to: friend ostream &operator<<(ostream&, string const &); > ... the constructor string( string& ) still > takes the reference of the constant object. Neither skipping the > constructor nor skipping the cont declaration is the answer, who knows > the answer. I don't think the problem has anything to do with the ctor. Rather, the attempt to pass a const string to a function expecting an ordinary one is what cfront is complaining about. This is correct. Note that if you adopt the second solution above you'll need to ensure that the operator<< function doesn't attempt to modify the string, or more errors will then be produced. Mike Mowbray Systems Development |||| OTC || ACSnet: mikem@otc.oz UUCP: {uunet,mcvax}!otc.oz!mikem Phone: (02) 287-4104 Snail: GPO Box 7000, Sydney 2001, Australia
weh@druhi.ATT.COM (HopkinsBWE) (12/30/87)
In article <370@targon.UUCP>, wim@targon.UUCP (Wim C. J. van Eerdt) writes: > #include <stream.h> > > class string { > //... > public: > > string(); > string( char* ); > string( string& ); > > friend ostream& operator<< ( ostream&, string& ); > > } ; > > const string text = "text"; > > void call() > { > > cout << text; // reference to a const object. > > } > > > A colleague typed the exhibited program and found an error on line > cout << text; > The message is correct: the 2nd argument of operator<< is a reference to a > string. So he changed the definition into > friend ostream& operator<< ( ostream&, string ); > Surprise, that did not work either: the constructor string( string& ) still > takes the reference of the constant object. Neither skipping the constructor > nor skipping the cont declaration is the answer, who knows the answer. Cfront won't allow one to pass a constant object by reference into a function unless the formal argument is also a constant. The error message from cfront (from a copy of the example in a file named ctest.c) is: CC ctest.c: "ctest.c", line 18: error: reference to const object 1 error Line 18 in my file is the ``cout << text; '' line. Thus, the function should have been declared as: friend ostream& operator<< ( ostream&, const string& ); Sure enough, cfront happily compiled it after the change. Since changes to parameters passed by reference change the actual argument, cfront cannot allow a constant to be passed as a non-constant reference. The solution of declaring the argument as simply a ``string'' fails because that requires the creation of a new copy of ``string'' from an existing string, meaning that string::string(string&) must be called. Since it declares the argument as a nonconstant reference, it suffers from the same problem as with operator>> (the same error message from cfront). The solution is similar: declare the constructor as ``string(const string&);''. This solution, too, has been confirmed by cfront. Bill Hopkins AT&T ihnp4!druhi!weh