C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Conditional expression between distinct pointer types error

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Kobi Cohen-Arazi
Guest





PostPosted: Sun Aug 29, 2004 10:45 pm    Post subject: Conditional expression between distinct pointer types error Reply with 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;
}

------------- 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





PostPosted: Mon Aug 30, 2004 10:52 am    Post subject: Re: Conditional expression between distinct pointer types er Reply with quote



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





PostPosted: Mon Aug 30, 2004 10:57 am    Post subject: Re: Conditional expression between distinct pointer types er Reply with quote



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





PostPosted: Mon Aug 30, 2004 11:49 pm    Post subject: Re: Conditional expression between distinct pointer types er Reply with quote


"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





PostPosted: Tue Aug 31, 2004 12:03 am    Post subject: Re: Conditional expression between distinct pointer types er Reply with quote

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





PostPosted: Tue Aug 31, 2004 12:12 am    Post subject: Re: Conditional expression between distinct pointer types er Reply with quote

[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





PostPosted: Tue Aug 31, 2004 10:19 am    Post subject: Re: Conditional expression between distinct pointer types er Reply with quote

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





PostPosted: Tue Aug 31, 2004 7:57 pm    Post subject: Re: Conditional expression between distinct pointer types er Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.