 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Kobi Cohen-Arazi Guest
|
Posted: Sun Aug 29, 2004 10:45 pm Post subject: Conditional expression between distinct pointer types error |
|
|
Hi all,
Consider the following example:
------------- Start Code a.cpp -------------------
class A {};
class B: public A {};
class C: public A {};
int main() {
B b;
C c;
A* pA = (1) ? &b : &c;
return 0;
}
------------- End Code a.cpp -------------------
on my g++
Reading specs from /usr/lib/gcc-lib/i586-suse-linux/3.3.1/specs
Configured with: ../configure --enable-threads=posix --prefix=/usr
--with-local-prefix=/usr/local --infodir=/usr/share/info
--mandir=/usr/share/man --libdir=/usr/lib
--enable-languages=c,c++,f77,objc,java,ada --disable-checking
--enable-libgcj --with-gxx-include-dir=/usr/include/g++
--with-slibdir=/lib --with-system-zlib --enable-shared
--enable-__cxa_atexit i586-suse-linux
Thread model: posix
gcc version 3.3.1 (SuSE Linux)
I get the following error:
| Quote: | g++ -c a.cpp
a.cpp: In function `int main()': |
a.cpp:9: error: conditional expression between distinct pointer types
`B*' and
`C*' lacks a cast
a.cpp:9: error: invalid conversion from `void*' to `A*'
Any idea why ?
A simple if will work, but why it doesn't work with the ?: operator
Thanks,
Kobi.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ivan Korotkov Guest
|
Posted: Mon Aug 30, 2004 10:52 am Post subject: Re: Conditional expression between distinct pointer types er |
|
|
| Quote: | ------------- Start Code a.cpp -------------------
class A {};
class B: public A {};
class C: public A {};
int main() {
B b;
C c;
A* pA = (1) ? &b : &c;
return 0;
}
------------- End Code a.cpp -------------------
I get the following error:
g++ -c a.cpp
a.cpp: In function `int main()':
a.cpp:9: error: conditional expression between distinct pointer types
`B*' and
`C*' lacks a cast
a.cpp:9: error: invalid conversion from `void*' to `A*'
Any idea why ?
A simple if will work, but why it doesn't work with the ?: operator
|
"If both expressions are of pointer types or if one is a pointer type and
the other is a constant expression that evaluates to 0, pointer
conversions are performed to convert them to a common type." (MSDN,
"Conditional operator ?:"
In this case, g++ thinks that the common type for C* and B* is void*
(though A* is a less general common type which would be more acceptable
here). Visual C++ 7.1 reports even a more dummy error:
error C2446: ':' : no conversion from 'C *' to 'B *'
so it tries to cast expr2 (&c) to the type of expr1 (B *).
If you want it to work, do this:
A *pa = static_cast<A *>((1) ? &b : &c));
--
Ivan
e-mail me at: korotkov2 at ztel dot ru
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
John Potter Guest
|
Posted: Mon Aug 30, 2004 10:57 am Post subject: Re: Conditional expression between distinct pointer types er |
|
|
On 29 Aug 2004 18:45:44 -0400, [email]kcarazi (AT) finjan (DOT) com[/email] (Kobi Cohen-Arazi)
wrote:
| Quote: | class A {};
class B: public A {};
class C: public A {};
int main() {
B b;
C c;
A* pA = (1) ? &b : &c;
|
A a;
A* pA2 = (1) ? &b : &a;
A* pA3 = (1) ? &a : &c;
| Quote: | }
Any idea why ?
A simple if will work, but why it doesn't work with the ?: operator
|
The requirements for ?: are that the two types are the same or that
one is convertable to the other. Both convertable to something else
is not supported.
John
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Sharad Kala Guest
|
Posted: Mon Aug 30, 2004 11:49 pm Post subject: Re: Conditional expression between distinct pointer types er |
|
|
"Kobi Cohen-Arazi" <kcarazi (AT) finjan (DOT) com> wrote in message
| Quote: | ------------- Start Code a.cpp -------------------
class A {};
class B: public A {};
class C: public A {};
int main() {
B b;
C c;
A* pA = (1) ? &b : &c;
return 0;
}
[snip]
g++ -c a.cpp
a.cpp: In function `int main()':
a.cpp:9: error: conditional expression between distinct pointer types
`B*' and
`C*' lacks a cast
a.cpp:9: error: invalid conversion from `void*' to `A*'
Any idea why ?
|
Because the second and third operands should be of the same type or a
suitable conversion should be present. A quote from 5.16/3 -
"if the second and third operand have different types, and either has
(possibly cv-qualified) class type, an attempt is made to convert each of
those operands to the type of the other". The section later defines the
conversions that are tried by the compiler.
-Sharad
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Motti Lanzkron Guest
|
Posted: Tue Aug 31, 2004 12:03 am Post subject: Re: Conditional expression between distinct pointer types er |
|
|
Kobi Cohen-Arazi wrote:
| Quote: | class A {};
class B: public A {};
class C: public A {};
int main() {
B b;
C c;
A* pA = (1) ? &b : &c;
return 0;
}
|
The second and third operands of the conditional expression must be
convertable to the same type. Since B* isn't convertable to C* and C*
isn't convertable to B* the compilation fails. If any one of the two
operands was an A* it would be OK.
A* pA = true? &b : static_cast<A*>(&c);
Ugly but OK.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Michiel Salters Guest
|
Posted: Tue Aug 31, 2004 12:12 am Post subject: Re: Conditional expression between distinct pointer types er |
|
|
[email]kcarazi (AT) finjan (DOT) com[/email] (Kobi Cohen-Arazi) wrote in message news:<d23dc578.0408290553.70d542fa (AT) posting (DOT) google.com>...
| Quote: | Hi all,
Consider the following example:
------------- Start Code a.cpp -------------------
class A {};
class B: public A {};
class C: public A {};
int main() {
B b;
C c;
A* pA = (1) ? &b : &c;
return 0;
}
|
The problem is that &b and &c have different types. The compiler
will not try to find a common base type. This is not too hard for
single inheritance, but with MI it is really hard. The compiler
also will not check the left side of the operator=, because
that's how C++ works. The ?: operator is not dependent on a later
operation.
Just use the obvious cast.
Regards,
Michiel Salters
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Old Wolf Guest
|
Posted: Tue Aug 31, 2004 10:19 am Post subject: Re: Conditional expression between distinct pointer types er |
|
|
Ivan Korotkov <clcppm-poster (AT) this (DOT) is.invalid> wrote:
| Quote: |
class A {};
class B: public A {};
class C: public A {};
int main() {
B b;
C c;
A* pA = (1) ? &b : &c;
g++ -c a.cpp
a.cpp: In function `int main()':
a.cpp:9: error: conditional expression between distinct pointer types
`B*' and
`C*' lacks a cast
a.cpp:9: error: invalid conversion from `void*' to `A*'
In this case, g++ thinks that the common type for C* and B* is void*
(though A* is a less general common type which would be more acceptable
here).
|
I wonder why it doesn't find A*. In fact my version of G++ won't
even find void*, and bombs out. Anyway...
| Quote: | If you want it to work, do this:
A *pa = static_cast<A *>((1) ? &b : &c));
|
This is undefined behaviour (assuming that the compiler decided that
the conditional expression had type "void *"). Let's rewrite so that
it is clearer:
void *pv = (1) ? &b : &c;
A *pa = static_cast<A *>(pv);
You can only convert from (void *) to (A *) if the pointer was
originally an (A *) before it was converted to (void *), which is
not the case here.
For example, if B was actually multiply-derived from D and A,
then pv is just a pointer to the first byte of the 'b' object,
and the static cast to A has no idea that it is actually an MI
object so you will end up with a horrible mess.
I'd suggest instead:
A* pa = (1) ? static_cast<A *>(&b) : &c;
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ivan Korotkov Guest
|
Posted: Tue Aug 31, 2004 7:57 pm Post subject: Re: Conditional expression between distinct pointer types er |
|
|
| Quote: | I wonder why it doesn't find A*. In fact my version of G++ won't
even find void*, and bombs out. Anyway...
|
Visual C++ 7.1 won't either. It says that it cannot find any conversion
from C * to B *.
| Quote: | A* pa = (1) ? static_cast<A *>(&b) : &c;
|
Yes, that's really better.
--
Ivan
e-mail me at: korotkov2 at ztel dot ru
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|