Fwd: Pointer casting related question

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Fwd: Pointer casting related question

gustav iv
Hi,

After a compilation trying of a sockets example code (https://goo.gl/ddDE8u), some errors gone.. and among them, a the pointer casting related one that I cannot solve by myself.

A function inside called socket_address_to_string() receives an smart pointer of type Glib::RefPtr<Gio::SocketAddress>... and seems need then to be cast to a pointer of type Glib::RefPtr<Gio::InetSocketAddress>...

How to solve it ?


(Exit of compilation)
---
$ g++ -std=c++14 client.cc -o client $(pkg-config --cflags --libs glibmm-2.4 giomm-2.4)
client.cc: In function ‘Glib::ustring {anonymous}::socket_address_to_string(const Glib::RefPtr<Gio::SocketAddress>&)’:
client.cc:71:77: error: no matching function for call to ‘dynamic_pointer_cast(const Glib::RefPtr<Gio::SocketAddress>&)’
   auto isockaddr = std::dynamic_pointer_cast<Gio::InetSocketAddress>(address);
                                                                             ^
In file included from /usr/include/c++/6/bits/shared_ptr.h:52:0,
                 from /usr/include/c++/6/condition_variable:44,
                 from client.cc:2:
/usr/include/c++/6/bits/shared_ptr_base.h:1334:5: note: candidate: template<class _Tp, class _Tp1, __gnu_cxx::_Lock_policy _Lp> std::__shared_ptr<_Tp1, _Lp> std::dynamic_pointer_cast(const std::__shared_ptr<_Tp2, _Lp>&)
     dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
     ^~~~~~~~~~~~~~~~~~~~
/usr/include/c++/6/bits/shared_ptr_base.h:1334:5: note:   template argument deduction/substitution failed:
client.cc:71:77: note:   ‘const Glib::RefPtr<Gio::SocketAddress>’ is not derived from ‘const std::__shared_ptr<_Tp2, _Lp>’
   auto isockaddr = std::dynamic_pointer_cast<Gio::InetSocketAddress>(address);
                                                                             ^
In file included from /usr/include/c++/6/condition_variable:44:0,
                 from client.cc:2:
/usr/include/c++/6/bits/shared_ptr.h:456:5: note: candidate: template<class _Tp, class _Tp1> std::shared_ptr<_Tp1> std::dynamic_pointer_cast(const std::shared_ptr<_Tp2>&)
     dynamic_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
     ^~~~~~~~~~~~~~~~~~~~
/usr/include/c++/6/bits/shared_ptr.h:456:5: note:   template argument deduction/substitution failed:
client.cc:71:77: note:   ‘const Glib::RefPtr<Gio::SocketAddress>’ is not derived from ‘const std::shared_ptr<_Tp2>’
   auto isockaddr = std::dynamic_pointer_cast<Gio::InetSocketAddress>(address);
                                                                             ^
client.cc: In function ‘int main(int, char**)’:
client.cc:148:3: error: ‘Type’ is not a member of ‘Gio::Socket’
   Gio::Socket::Type socket_type;
   ^~~
client.cc:191:3: error: ‘socket_type’ was not declared in this scope
   socket_type = use_udp ? Gio::Socket::Type::DATAGRAM : Gio::Socket::Type::STREAM;
   ^~~~~~~~~~~
client.cc:191:40: error: ‘Gio::Socket::Type’ has not been declared
   socket_type = use_udp ? Gio::Socket::Type::DATAGRAM : Gio::Socket::Type::STREAM;
                                        ^~~~
client.cc:191:70: error: ‘Gio::Socket::Type’ has not been declared
  socket_type = use_udp ? Gio::Socket::Type::DATAGRAM : Gio::Socket::Type::STREAM;
                                                                     ^~~~
client.cc:192:30: error: ‘IPV6’ is not a member of ‘Gio::SocketFamily’
   socket_family = use_ipv6 ? Gio::SocketFamily::IPV6 : Gio::SocketFamily::IPV4;
                              ^~~
client.cc:192:56: error: ‘IPV4’ is not a member of ‘Gio::SocketFamily’
   socket_family = use_ipv6 ? Gio::SocketFamily::IPV6 : Gio::SocketFamily::IPV4;
                                                        ^~~
client.cc:196:75: error: ‘Gio::Socket::Protocol’ has not been declared
 cket = Gio::Socket::create(socket_family, socket_type, Gio::Socket::Protocol::DEFAULT);
                                                                     ^~~~~~~~
client.cc:275:53: error: ‘OUT’ is not a member of ‘Glib::IOCondition’
       ensure_condition(socket, "send", cancellable, Glib::IOCondition::OUT);
                                                     ^~~~
client.cc:308:54: error: ‘IN’ is not a member of ‘Glib::IOCondition’
     ensure_condition(socket, "receive", cancellable, Glib::IOCondition::IN);



_______________________________________________
gtkmm-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtkmm-list
Reply | Threaded
Open this post in threaded view
|

Re: Pointer casting related question

Daniel Boles
use Glib::RefPtr<destination_type>::cast_dynamic(source_refptr)

or cast_static if you can guarantee that the cast is valid, does not require adjustment for multiple/virtual inheritance, and don't want the (probably insignificant) overhead of a checked cast.

see:
https://developer.gnome.org/glibmm/stable/classGlib_1_1RefPtr.html#afba688c406f0c3d1239c6b7c3716c1de
https://mail.gnome.org/archives/gtkmm-list/2010-August/msg00051.html



_______________________________________________
gtkmm-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtkmm-list
Reply | Threaded
Open this post in threaded view
|

Re: Pointer casting related question

Daniel Boles
In reply to this post by gustav iv
On 7 August 2017 at 13:55, gustav iv <[hidden email]> wrote:
Hi,

After a compilation trying of a sockets example code (https://goo.gl/ddDE8u), some errors gone.. and among them, a the pointer casting related one that I cannot solve by myself.


It looks to me like the root of your problem is that you are trying to compile an example for glibmm master/next, but while linking to the glibmm-2.4 ABI... That won't work. In glibmm next, Glib::RefPtr is now an std::shared_ptr, hence the std:: casts in the example code, but that will not work in glibmm-2.4 where RefPtr is a completely custom class.

Presumably you should look for the corresponding example code in the right branch of glibmm, then your errors will all vanish.



_______________________________________________
gtkmm-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtkmm-list
Reply | Threaded
Open this post in threaded view
|

Re: Pointer casting related question

Chris Vine-3
In reply to this post by Daniel Boles
On Mon, 7 Aug 2017 13:58:07 +0100
Daniel Boles <[hidden email]> wrote:
> use Glib::RefPtr<destination_type>::cast_dynamic(source_refptr)
>
> or cast_static if you can guarantee that the cast is valid, does not
> require adjustment for multiple/virtual inheritance, and don't want
> the (probably insignificant) overhead of a checked cast.
>
> see:
> https://developer.gnome.org/glibmm/stable/classGlib_1_1RefPtr.html#afba688c406f0c3d1239c6b7c3716c1de
> https://mail.gnome.org/archives/gtkmm-list/2010-August/msg00051.html

A static cast will carry out pointer adjustment when traversing an
inheritance graph to account for multiple inheritance or a vtable.  It
is reinterpret cast which will not.

A static cast does not allow a direct cast between two siblings in
a multiple inheritance graph (you will get a compiler error unless you
do it in two stages via a common parent), and as you say it does not
check for validity.
_______________________________________________
gtkmm-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtkmm-list
Reply | Threaded
Open this post in threaded view
|

Re: Pointer casting related question

Daniel Boles
On 7 August 2017 at 14:59, Chris Vine <[hidden email]> wrote:
A static cast will carry out pointer adjustment when traversing an
inheritance graph to account for multiple inheritance or a vtable.  It
is reinterpret cast which will not.

Indeed, thanks. I was only half-thinking at the time, and decided to err on the side of caution. :)

I am one of the seemingly unpopular people who think it's perfectly fine to static_cast if you know the conversion will always be valid - i.e. so long as the program is not already in the process of crashing or failing asserts, which obviously should not be treated as reachable in released builds.

I often wish the stdlib had an asserted_static_cast<T>(arg) as this is a pattern I use often:
    assert( dynamic_cast<T>(arg) );
    auto& ref = *static_cast<T>(arg);
    // Use ref

and I've not yet gotten around to creating my own little header to reduce the verbosity of this.


_______________________________________________
gtkmm-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtkmm-list
Reply | Threaded
Open this post in threaded view
|

Re: Pointer casting related question

Chris Vine-3
On Mon, 7 Aug 2017 15:04:48 +0100
Daniel Boles <[hidden email]> wrote:

> On 7 August 2017 at 14:59, Chris Vine <[hidden email]> wrote:
>
> > A static cast will carry out pointer adjustment when traversing an
> > inheritance graph to account for multiple inheritance or a vtable.
> > It is reinterpret cast which will not.
> >  
>
> Indeed, thanks. I was only half-thinking at the time, and decided to
> err on the side of caution. :)
>
> I am one of the seemingly unpopular people who think it's perfectly
> fine to static_cast if you know the conversion will always be valid -
> i.e. so long as the program is not already in the process of crashing
> or failing asserts, which obviously should not be treated as
> reachable in released builds.

I agree with you.  I rarely use dynamic_cast (and I rarely use virtual
inheritance - mainly only for type erasure).  In practice you usually
know statically what your object consists of.
_______________________________________________
gtkmm-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtkmm-list