views:

403

answers:

2

Using boost 1.4.2 asio in a c++ app and getting linux compiler warnings i don't grok.

still here?
The app i'm working on needs a "socket" that might be an ssl socket or a regular tcp socket so we hide specifics behind a template "socket" class that takes either an ssl socket class or tcp socket class as template parameter - below is the ssl class code.
The app runs properly without any optimization turned on; the issue is when i compile under linux g++ 4.4.1 and turn on optimization at -02 or higher, the -fstrict-aliasing flag is turned on. Compiling results in strict aliasing warnings along the lines of: "warning: dereferencing type-punned pointer will break strict-aliasing rules" everywhere i dereference _psock (eg _psock->handshake)

I'd like to know why this warning is being issued, and does it indicate a design problem...

class socket_ssl_cli
{
public:

    typedef ba::ssl::stream<ba::ip::tcp::socket> socket_type;
    socket_ssl_cli(ba::io_service& io_svc, SocketConfig & sockcfg)
        : _io_svc(io_svc)
        , _ctxt(_io_svc, ba::ssl::context::tlsv1)
        , _psock(0)
    {
        try {
            // the one and only ssl context
            // hardcoded for test, but get these values from config
            _ctxt.set_options(ba::ssl::context::default_workarounds | 
                                ba::ssl::context::verify_none);

            _psock = new socket_type(_io_svc, _ctxt);
        } catch (bs::system_error & x) {
            throw std::runtime_error(x.code().message());
        }

    }

    ~socket_ssl_cli() 
    { 
        if (_psock) {
            bs::error_code ec;
            close_socket(ec); 
            delete _psock; 
        }
    }

    socket_type & raw_socket() { return *_psock; }

    void setup(bs::error_code & ec)
    {
        _psock->handshake(ba::ssl::stream_base::client, ec);
    }

    void close_socket(bs::error_code & ec) 
    { 
        // shut down ssl, then shutdown socket, then close socket
        _psock->shutdown(ec);
        _psock->lowest_layer().shutdown(ba::socket_base::shutdown_both, ec);
        _psock->lowest_layer().close(ec);
    }

private:

    ba::io_service & _io_svc;
    ba::ssl::context _ctxt;
    socket_type * _psock;
};

all the painful compile output with -02 turned on, which results in -fstrict-aliasing

../../../../third-party/boost/1.42.0/boost/function/function_base.hpp:321: warning: dereferencing type-punned pointer will break strict-aliasing rules ../../../../third-party/boost/1.42.0/boost/function/function_base.hpp:325: warning: dereferencing type-punned pointer will break strict-aliasing rules ../../../../third-party/boost/1.42.0/boost/function/function_base.hpp: In static member function ‘static void boost::detail::function::functor_manager_common::manage_small(const boost::detail::function::function_buffer&, boost::detail::function::function_buffer&, boost::detail::function::functor_manager_operation_type) [with Functor = boost::_bi::bind_t > > >, boost::_bi::list1 > >*> > >]’: ../../../../third-party/boost/1.42.0/boost/function/function_base.hpp:360: instantiated from ‘static void boost::detail::function::functor_manager::manager(const boost::detail::function::function_buffer&, boost::detail::function::function_buffer&, boost::detail::function::functor_manager_operation_type, mpl_::true_) [with Functor = boost::_bi::bind_t > > >, boost::_bi::list1 > >*> > >]’ ../../../../third-party/boost/1.42.0/boost/function/function_base.hpp:406: instantiated from ‘static void boost::detail::function::functor_manager::manager(const boost::detail::function::function_buffer&, boost::detail::function::function_buffer&, boost::detail::function::functor_manager_operation_type, boost::detail::function::function_obj_tag) [with Functor = boost::_bi::bind_t > > >, boost::_bi::list1 > >*> > >]’ ../../../../third-party/boost/1.42.0/boost/function/function_base.hpp:434: instantiated from ‘static void boost::detail::function::functor_manager::manage(const boost::detail::function::function_buffer&, boost::detail::function::function_buffer&, boost::detail::function::functor_manager_operation_type) [with Functor = boost::_bi::bind_t > > >, boost::_bi::list1 > >*> > >]’ ../../../../third-party/boost/1.42.0/boost/function/function_template.hpp:913: instantiated from ‘void boost::function0::assign_to(Functor) [with Functor = boost::_bi::bind_t > > >, boost::_bi::list1 > >*> > >, R = int]’ ../../../../third-party/boost/1.42.0/boost/function/function_template.hpp:722: instantiated from ‘boost::function0::function0(Functor, typename boost::enable_if_c::type) [with Functor = boost::_bi::bind_t > > >, boost::_bi::list1 > >*> > >, R = int]’ ../../../../third-party/boost/1.42.0/boost/function/function_template.hpp:1064: instantiated from ‘boost::function::function(Functor, typename boost::enable_if_c::type) [with Functor = boost::_bi::bind_t > > >, boost::_bi::list1 > >*> > >, R = int]’ ../../../../third-party/boost/1.42.0/boost/function/function_template.hpp:1105: instantiated from ‘typename boost::enable_if_c&>::type boost::function::operator=(Functor) [with Functor = boost::_bi::bind_t > > >, boost::_bi::list1 > >*> > >, R = int]’ ../../../../third-party/boost/1.42.0/boost/asio/ssl/detail/openssl_operation.hpp:134: instantiated from ‘boost::asio::ssl::detail::openssl_operation::openssl_operation(boost::asio::ssl::detail::ssl_primitive_func, Stream&, boost::asio::ssl::detail::net_buffer&, SSL*, BIO*) [with Stream = boost::asio::basic_stream_socket >]’ ../../../../third-party/boost/1.42.0/boost/asio/ssl/detail/openssl_stream_service.hpp:510: instantiated from ‘boost::system::error_code boost::asio::ssl::detail::openssl_stream_service::handshake(boost::asio::ssl::detail::openssl_stream_service::impl_struct*&, Stream&, boost::asio::ssl::stream_base::handshake_type, boost::system::error_code&) [with Stream = boost::asio::basic_stream_socket >]’ ../../../../third-party/boost/1.42.0/boost/asio/ssl/stream_service.hpp:100: instantiated from ‘boost::system::error_code boost::asio::ssl::stream_service::handshake(boost::asio::ssl::detail::openssl_stream_service::impl_struct*&, Stream&, boost::asio::ssl::stream_base::handshake_type, boost::system::error_code&) [with Stream = boost::asio::basic_stream_socket >]’ ../../../../third-party/boost/1.42.0/boost/asio/ssl/stream.hpp:207: instantiated from ‘boost::system::error_code boost::asio::ssl::stream::handshake(boost::asio::ssl::stream_base::handshake_type, boost::system::error_code&) [with Stream = boost::asio::basic_stream_socket >, Service = boost::asio::ssl::stream_service]’ ../sockets/socket_ssl_cli.h:45: instantiated from here

+1  A: 

read the boost wiki explaining compiler warning guidelines

https://svn.boost.org/trac/boost/wiki/Guidelines/WarningsGuidelines

they have a whole section dedicated to -fstrict-aliasing

-fstrict-aliasing - also turned on by -O2, -O3 and -Os. Tells the compiler that it's ok to do a certain class of optimization based on the type of expressions. In particular you're promising by using this flag that an object of one type won't reside at the same address as an object of an incompatible type. -fno-strict-aliasing - turns off this optimization. If this changes the behavior of your code, you have a problem in your code.

This is trying to let you know that you are asking the compiler to do undefined behavior and it may not do what you think it will do. As the optimization level increases, the liklihood that you won't like what it does will increase. I show a simple example later that surprisingly generates the wrong result when optimization at any level is turned on. Ignore this warning at your own peril. You are unlikely to care for the undefined behavior that results.

Sam Miller
A: 

I'm having a similar issue with gcc-4.4.4 (Debian Squeeze). I went through a Boost mailing list thread related to this. However, in the end I'm still confused as to whose problem it is. Whether GCC's or Boost's. :-S I've resorted to -fno-strict-aliasing in my code.

Joe Steeve