vaughan@puma.cad.mcc.com (Paul Vaughan) (04/12/90)
The following program compiles cleanly under g++-1.37.1, but gets three errors under cfront (Sun CC, actually). --------------------------- class Int { int i; public: Int(int j) : i(j) {} Int(Int& I) { i = I.i; } operator int() { return i; } operator int&() { return i; } }; main() { Int i = 4; i += i; // line 29 } ------------------------ CC -c convert.cc CC convert.cc: "convert.cc", line 30: error: ambiguous conversion of Int "convert.cc", line 30: error: ambiguous conversion of Int "convert.cc", line 30: error: bad operand types Int Int for += 3 errors Any comments on why CC generates these errors, and whether or not this is the right thing to do? I realize that a class that works Exactly like an int for both reading and assignment probably isn't very useful, but should I be able to do it this way? Paul Vaughan, MCC CAD Program | ARPA: vaughan@mcc.com | Phone: [512] 338-3639 Box 200195, Austin, TX 78720 | UUCP: ...!cs.utexas.edu!milano!cadillac!vaughan
spencer@egypt.mpr.ca ( Reid Spencer) (04/13/90)
In article <7633@cadillac.CAD.MCC.COM>, vaughan@puma.cad.mcc.com (Paul Vaughan) writes: > > The following program compiles cleanly under g++-1.37.1, but gets > three errors under cfront (Sun CC, actually). > example omitted. > > Any comments on why CC generates these errors, and whether or not this > is the right thing to do? I realize that a class that works Exactly > like an int for both reading and assignment probably isn't very > useful, but should I be able to do it this way? > I'm not sure what you were intending with this example, but at first appearances it seems you simply forgot to override the "+=" operator for class "Int". I think, perhaps that you expected cfront to use the constructor to add the value of i to itself. However, even if that were semantically possible it wouldn't provide the results you want (i.i being 8, not 4). Why g++ accepts this program, I don't know. It's probably a bug in g++. cfront seems to be giving you the right messages. Here's the program with some modifications I made: ------------------------------------------ extern "C" { int printf(char *, ...); }; // new class Int { int i; public: Int(int j) : i(j) {} Int(Int& I) { i = I.i; } operator int() { return i; } operator int&() { return i; } Int & operator +=(Int &j) { i += j.i; return *this; } // new Int & operator +=(int j) { i += j; return *this; } // new }; main() { Int i = 4; i += i; // line 29 i += 1; // new printf("i.i is %d\n", int(i)); // new } ---------------------------------------------- The printf statement should print "i.i is 9". This kind of problem is a common misperception in C++. Please make note of the following statement: "the semantics of initialization and assignment are different". See Lippman's book "C++ Primer", pp. 243 and 268 for details. Also in Stroustrup, pp 178-180. Hope this helps ... _______________________________________________________________________________ Reid Spencer Software Engineer Voice: (604) 293-5334 MPR TelTech, Ltd. Fax: (604) 293-5787 8999 Nelson Way, Burnaby, BC Internet: spencer@egypt.mpr.ca Canada V5A 4B5 UUCP: uw-beaver!ubc-cs!eric!egypt!spencer
jimad@microsoft.UUCP (Jim ADCOCK) (04/14/90)
In article <7633@cadillac.CAD.MCC.COM| vaughan@puma.cad.mcc.com (Paul Vaughan) writes: | |The following program compiles cleanly under g++-1.37.1, but gets |three errors under cfront (Sun CC, actually). | |--------------------------- |class Int { | int i; |public: | Int(int j) : i(j) {} | Int(Int& I) { i = I.i; } | operator int() { return i; } | operator int&() { return i; } |}; | |main() { | Int i = 4; | i += i; // line 29 |} | |------------------------ |CC -c convert.cc |CC convert.cc: |"convert.cc", line 30: error: ambiguous conversion of Int |"convert.cc", line 30: error: ambiguous conversion of Int |"convert.cc", line 30: error: bad operand types Int Int for += |3 errors | |Any comments on why CC generates these errors, and whether or not this |is the right thing to do? I realize that a class that works Exactly |like an int for both reading and assignment probably isn't very |useful, but should I be able to do it this way? See Hansen "The C++ Answer Book" pg 251, etc. My question would be why g++ accepts this program? To do so surely represents an extension to the language. I would guess this might be because g++ interprets x += y as x = x + y and counts on the optimizer to keep x from being evaluated more than once? --- Given that += is not overloaded in Int, the += referred to must be of the form int x += int y. How then does the compiler make the int x out of an Int i? There are two ways: Use operator int or use operator int&. The disambiguating rules of C++ do not say which operator to use, therefor the left hand side "x" is ambiguous. How does the compiler make the int y out of an Int i? There are two ways: Use operator int or use operator int&. The disambiguating rules of C++ do not say which operator to use, therefor the right hand side "y" is ambiguous. So we cannot do the conversions. Is there then a += we can use given an Int += Int ? No. --- Please note that Hanson's comments about not being able to differentiate pre and post inc and dec have been superceeded by popular demand -- to differentiate declare: operator++() // prefix ++a operator++(int); // postfix a++ -- assuming you have a very recent release compiler that actually supports this hack. [ This according to the illuminated bible section 13.4.7 ]
jimad@microsoft.UUCP (Jim ADCOCK) (04/14/90)
>I realize that a class that works Exactly >like an int for both reading and assignment probably isn't very >useful, but should I be able to do it this way? Actually, such a beast might actually be vaguely useful -- because it differs from int in one important way: INT is a first-class class and as such can be inherited from, whereas int is a primitive. Consider a class LINK and a class INT: create LINKED_INT by multiplying inheriting from LINK and INT. LINKED_INTs can be linked together and tranversed using the capabilities of LINK, and LINKED_INTs can be used as-if ints in math expressions. ....one could then go on and use these capabilities to make queues of INTs or stacks of INTs if one was really perverse.... Weak example, but you get my drift.
c60c-2ca@e260-2d.berkeley.edu (Andrew Choi) (04/14/90)
In article <7633@cadillac.CAD.MCC.COM> vaughan@puma.cad.mcc.com (Paul Vaughan) writes: > >The following program compiles cleanly under g++-1.37.1, but gets >three errors under cfront (Sun CC, actually). > >--------------------------- >class Int { > int i; >public: > Int(int j) : i(j) {} > Int(Int& I) { i = I.i; } > operator int() { return i; } > operator int&() { return i; } >}; > >main() { > Int i = 4; > i += i; // line 29 >} > >------------------------ >CC -c convert.cc >CC convert.cc: >"convert.cc", line 30: error: ambiguous conversion of Int >"convert.cc", line 30: error: ambiguous conversion of Int >"convert.cc", line 30: error: bad operand types Int Int for += >3 errors The code is incorrect because the user-defined conversion, namely, "operator int()" is ambiguous. Also, this conversion is not applied in line 29, resulting in the third error message. For the first error, please consider the following: Int i; i = i + 3; For the second instance of i (the r-value), either "operator int()" or "operator int&()" can be applied to convert "i" to an integer. For the second error, the conversion "operator int()" is not applied because there is no indication that it should be invoked since no integer is involved in that expression. Rather, the compiler is looking for the function "operator +=(Int &, Int)". Andrew Choi Internet Address: c60c-2ca@web.berkeley.edu Standard Disclaimer