Prev: will taking the address of the first element of a string break COW strings?
Next: iterator invalidation guarantees in tr1::unordered_map
From: Ike Naar on 7 Jul 2010 12:57 The code below shows different behaviour with different compilers, and I wonder which behaviour is the right one. There's a struct X that has conversion operators to bool and to double, Instances of this struct are used in a boolean context. The idea is that the X instances are implicitly converted to bool. /* code starts here */ #include <iostream> struct X { X(int id) : m_id(id) {} operator bool() const { std::cout << m_id << ":bool\n"; return false; } operator double() const { std::cout << m_id << ":double\n"; return 0.0; } int m_id; }; int main() { X x0(0), x1(1); bool b = x0 || x1; /* line 14 */ return b; } /* code ends here */ GNU C++ compiles it without warnings, and the run-time output is: 0:bool 1:bool Sun C++ 5.9 compiles it without warnings, and the run-time output is: 0:double 1:double Sun C++ 5.6 gives the following compilation errors: "a.cpp", line 14: Error: Overloading ambiguity between "X::operator bool() const" and "X::operator double() const". "a.cpp", line 14: Error: Overloading ambiguity between "X::operator bool() const" and "X::operator double() const". The GNU C++ behaviour (implicit conversion to bool) is what I had expected, and the Sun C++ behaviour came a bit as a surprise. If the conversions are made explicit: bool b = bool(x0) || bool(x1); /* line 14 */ then all three compilers behave as expected, so that would solve the ambiguity, but still I'm wondering whether the original code has well-defined behaviour, and, if so, which compiler is doing the right thing? -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Ian Collins on 7 Jul 2010 22:12 On 07/ 8/10 03:57 PM, Ike Naar wrote: > The code below shows different behaviour with different compilers, > and I wonder which behaviour is the right one. > There's a struct X that has conversion operators to bool and to double, > Instances of this struct are used in a boolean context. > The idea is that the X instances are implicitly converted to bool. > > /* code starts here */ > > #include<iostream> > > struct X > { > X(int id) : m_id(id) {} > operator bool() const { std::cout<< m_id<< ":bool\n"; return false; } > operator double() const { std::cout<< m_id<< ":double\n"; return 0.0; } > int m_id; > }; > > int main() > { > X x0(0), x1(1); > bool b = x0 || x1; /* line 14 */ > return b; > } > > /* code ends here */ > > GNU C++ compiles it without warnings, and the run-time output is: > 0:bool > 1:bool > > Sun C++ 5.9 compiles it without warnings, and the run-time output is: > 0:double > 1:double Sun C++ 5.10 compiles it without warnings, and the run-time output is the same as g++. > Sun C++ 5.6 gives the following compilation errors: > "a.cpp", line 14: Error: Overloading ambiguity between > "X::operator bool() const" and "X::operator double() const". > "a.cpp", line 14: Error: Overloading ambiguity between > "X::operator bool() const" and "X::operator double() const". > > The GNU C++ behaviour (implicit conversion to bool) is what I had expected, > and the Sun C++ behaviour came a bit as a surprise. It's probably a bug in the older compiler. A search of the bugs listed in compiler patches or the compiler forum might show the issue. -- Ian Collins [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Daniel Krügler on 10 Jul 2010 23:26 On 8 Jul., 05:57, i...(a)localhost.claranet.nl (Ike Naar) wrote: > The code below shows different behaviour with different compilers, > and I wonder which behaviour is the right one. > There's a struct X that has conversion operators to bool and to double, > Instances of this struct are used in a boolean context. > The idea is that the X instances are implicitly converted to bool. > > /* code starts here */ > > #include <iostream> > > struct X > { > X(int id) : m_id(id) {} > operator bool() const { std::cout << m_id << ":bool\n"; return false; } > operator double() const { std::cout << m_id << ":double\n"; return 0.0; } > int m_id; > }; > > int main() > { > X x0(0), x1(1); > bool b = x0 || x1; /* line 14 */ > return b; > } > > /* code ends here */ [..] > Sun C++ 5.6 gives the following compilation errors: > "a.cpp", line 14: Error: Overloading ambiguity between > "X::operator bool() const" and "X::operator double() const". > "a.cpp", line 14: Error: Overloading ambiguity between > "X::operator bool() const" and "X::operator double() const". > > The GNU C++ behaviour (implicit conversion to bool) is what I had expected, > and the Sun C++ behaviour came a bit as a surprise. > > If the conversions are made explicit: > > bool b = bool(x0) || bool(x1); /* line 14 */ > > then all three compilers behave as expected, so that would solve the > ambiguity, but still I'm wondering whether the original code has well-defined > behaviour, and, if so, which compiler is doing the right thing? I think that Sun C++ 5.6 does this incorrect. According to [over.built]/26 the only relevant candidate operator function is bool operator||(bool, bool); and thus the conversion to bool is the only possible one. It is correct that the current language has still some open points in regard to built-in candidate operators, among those problems with assignments: http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#260 http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#507 and equality: http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#545 http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#954 but I don't see how they could be related to your example. HTH & Greetings from Bremen, Daniel Kr�gler -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: litb on 10 Jul 2010 23:27
On 8 Jul., 05:57, i...(a)localhost.claranet.nl (Ike Naar) wrote: > The code below shows different behaviour with different compilers, > and I wonder which behaviour is the right one. > There's a struct X that has conversion operators to bool and to double, > Instances of this struct are used in a boolean context. > The idea is that the X instances are implicitly converted to bool. > > /* code starts here */ > > #include <iostream> > > struct X > { > X(int id) : m_id(id) {} > operator bool() const { std::cout << m_id << ":bool\n"; return false; } > operator double() const { std::cout << m_id << ":double\n"; return 0.0; } > int m_id; > > }; > > int main() > { > X x0(0), x1(1); > bool b = x0 || x1; /* line 14 */ > return b; > > } > > /* code ends here */ > > GNU C++ compiles it without warnings, and the run-time output is: > 0:bool > 1:bool > > Sun C++ 5.9 compiles it without warnings, and the run-time output is: > 0:double > 1:double > > Sun C++ 5.6 gives the following compilation errors: > "a.cpp", line 14: Error: Overloading ambiguity between > "X::operator bool() const" and "X::operator double() const". > "a.cpp", line 14: Error: Overloading ambiguity between > "X::operator bool() const" and "X::operator double() const". > > The GNU C++ behaviour (implicit conversion to bool) is what I had expected, > and the Sun C++ behaviour came a bit as a surprise. > > If the conversions are made explicit: > > bool b = bool(x0) || bool(x1); /* line 14 */ > > then all three compilers behave as expected, so that would solve the > ambiguity, but still I'm wondering whether the original code has well-defined > behaviour, and, if so, which compiler is doing the right thing? > Overload resolution of the builtin operator is "operator||(bool, bool)". Let's construct an equivalent situation void f(bool); void g() { X x0(0); f(x0); } X can be converted to bool by using operator bool and operator double. During overload resolution for the conversion functions, "operator bool" is preferred over "operator double" (which could do the job too) because bool->bool is better than double->bool. The user defined conversion sequence is thus "X -> (operator bool) -> bool", for the conversion "X -> bool", and there is no ambiguity. GCC is correct. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |