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