Change ip::address default constructor to be not-an-address.
diff --git a/asio/include/asio/ip/address.hpp b/asio/include/asio/ip/address.hpp
index 3b79837..9aeafd5 100644
--- a/asio/include/asio/ip/address.hpp
+++ b/asio/include/asio/ip/address.hpp
@@ -179,7 +179,7 @@
   }
 
   // The type of the address.
-  enum { ipv4, ipv6 } type_;
+  enum { none, ipv4, ipv6 } type_;
 
   // The underlying IPv4 address.
   asio::ip::address_v4 ipv4_address_;
diff --git a/asio/include/asio/ip/basic_endpoint.hpp b/asio/include/asio/ip/basic_endpoint.hpp
index 60dcbfa..d9a0569 100644
--- a/asio/include/asio/ip/basic_endpoint.hpp
+++ b/asio/include/asio/ip/basic_endpoint.hpp
@@ -124,9 +124,9 @@
   /// The protocol associated with the endpoint.
   protocol_type protocol() const
   {
-    if (impl_.is_v4())
-      return InternetProtocol::v4();
-    return InternetProtocol::v6();
+    if (impl_.is_v6())
+      return InternetProtocol::v6();
+    return InternetProtocol::v4();
   }
 
   /// Get the underlying endpoint in the native type.
diff --git a/asio/include/asio/ip/detail/endpoint.hpp b/asio/include/asio/ip/detail/endpoint.hpp
index 630908f..ff46dcd 100644
--- a/asio/include/asio/ip/detail/endpoint.hpp
+++ b/asio/include/asio/ip/detail/endpoint.hpp
@@ -111,6 +111,12 @@
     return data_.base.sa_family == ASIO_OS_DEF(AF_INET);
   }
 
+  // Determine whether the endpoint is IPv6.
+  bool is_v6() const
+  {
+    return data_.base.sa_family == ASIO_OS_DEF(AF_INET6);
+  }
+
 #if !defined(ASIO_NO_IOSTREAM)
   // Convert to a string.
   ASIO_DECL std::string to_string(asio::error_code& ec) const;
diff --git a/asio/include/asio/ip/detail/impl/endpoint.ipp b/asio/include/asio/ip/detail/impl/endpoint.ipp
index aa8c47f..01a4de5 100644
--- a/asio/include/asio/ip/detail/impl/endpoint.ipp
+++ b/asio/include/asio/ip/detail/impl/endpoint.ipp
@@ -50,7 +50,7 @@
       asio::detail::socket_ops::host_to_network_short(port_num);
     data_.v4.sin_addr.s_addr = ASIO_OS_DEF(INADDR_ANY);
   }
-  else
+  else if (family == ASIO_OS_DEF(AF_INET6))
   {
     data_.v6.sin6_family = ASIO_OS_DEF(AF_INET6);
     data_.v6.sin6_port =
@@ -66,6 +66,13 @@
     data_.v6.sin6_addr.s6_addr[14] = 0, data_.v6.sin6_addr.s6_addr[15] = 0;
     data_.v6.sin6_scope_id = 0;
   }
+  else
+  {
+    data_.v4.sin_family = ASIO_OS_DEF(AF_UNSPEC);
+    data_.v4.sin_port =
+      asio::detail::socket_ops::host_to_network_short(port_num);
+    data_.v4.sin_addr.s_addr = ASIO_OS_DEF(INADDR_ANY);
+  }
 }
 
 endpoint::endpoint(const asio::ip::address& addr,
@@ -83,7 +90,7 @@
           static_cast<asio::detail::u_long_type>(
             address_cast<address_v4>(addr).to_ulong()));
   }
-  else
+  else if (addr.is_v6())
   {
     data_.v6.sin6_family = ASIO_OS_DEF(AF_INET6);
     data_.v6.sin6_port =
@@ -96,11 +103,18 @@
       static_cast<asio::detail::u_long_type>(
         v6_addr.scope_id());
   }
+  else
+  {
+    data_.v4.sin_family = ASIO_OS_DEF(AF_UNSPEC);
+    data_.v4.sin_port =
+      asio::detail::socket_ops::host_to_network_short(port_num);
+    data_.v4.sin_addr.s_addr = ASIO_OS_DEF(INADDR_ANY);
+  }
 }
 
 void endpoint::resize(std::size_t new_size)
 {
-  if (new_size > sizeof(asio::detail::sockaddr_storage_type))
+  if (new_size > sizeof(data_))
   {
     asio::error_code ec(asio::error::invalid_argument);
     asio::detail::throw_error(ec);
@@ -109,28 +123,28 @@
 
 unsigned short endpoint::port() const
 {
-  if (is_v4())
+  if (is_v6())
   {
     return asio::detail::socket_ops::network_to_host_short(
-        data_.v4.sin_port);
+        data_.v6.sin6_port);
   }
   else
   {
     return asio::detail::socket_ops::network_to_host_short(
-        data_.v6.sin6_port);
+        data_.v4.sin_port);
   }
 }
 
 void endpoint::port(unsigned short port_num)
 {
-  if (is_v4())
+  if (is_v6())
   {
-    data_.v4.sin_port
+    data_.v6.sin6_port
       = asio::detail::socket_ops::host_to_network_short(port_num);
   }
   else
   {
-    data_.v6.sin6_port
+    data_.v4.sin_port
       = asio::detail::socket_ops::host_to_network_short(port_num);
   }
 }
@@ -144,7 +158,7 @@
         asio::detail::socket_ops::network_to_host_long(
           data_.v4.sin_addr.s_addr));
   }
-  else
+  else if (is_v6())
   {
     asio::ip::address_v6::bytes_type bytes;
 #if defined(ASIO_HAS_STD_ARRAY)
@@ -154,6 +168,10 @@
 #endif // defined(ASIO_HAS_STD_ARRAY)
     return asio::ip::address_v6(bytes, data_.v6.sin6_scope_id);
   }
+  else
+  {
+    return asio::ip::address();
+  }
 }
 
 void endpoint::address(const asio::ip::address& addr)
diff --git a/asio/include/asio/ip/impl/address.ipp b/asio/include/asio/ip/impl/address.ipp
index 8170053..5f4e0de 100644
--- a/asio/include/asio/ip/impl/address.ipp
+++ b/asio/include/asio/ip/impl/address.ipp
@@ -30,7 +30,7 @@
 namespace ip {
 
 address::address()
-  : type_(ipv4),
+  : type_(none),
     ipv4_address_(),
     ipv6_address_()
 {
@@ -158,46 +158,81 @@
 
 std::string address::to_string() const
 {
-  if (type_ == ipv6)
+  switch (type_)
+  {
+  case ipv4:
+    return ipv4_address_.to_string();
+  case ipv6:
     return ipv6_address_.to_string();
-  return ipv4_address_.to_string();
+  default:
+    bad_address_cast ex;
+    asio::detail::throw_exception(ex);
+    return std::string();
+  }
 }
 
 std::string address::to_string(asio::error_code& ec) const
 {
-  if (type_ == ipv6)
+  switch (type_)
+  {
+  case ipv4:
+    return ipv4_address_.to_string(ec);
+  case ipv6:
     return ipv6_address_.to_string(ec);
-  return ipv4_address_.to_string(ec);
+  default:
+    ec = asio::error::invalid_argument;
+    return std::string();
+  }
 }
 
 bool address::is_loopback() const
 {
-  return (type_ == ipv4)
-    ? ipv4_address_.is_loopback()
-    : ipv6_address_.is_loopback();
+  switch (type_)
+  {
+  case ipv4:
+    return ipv4_address_.is_loopback();
+  case ipv6:
+    return ipv6_address_.is_loopback();
+  default:
+    return false;
+  }
 }
 
 bool address::is_unspecified() const
 {
-  return (type_ == ipv4)
-    ? ipv4_address_.is_unspecified()
-    : ipv6_address_.is_unspecified();
+  switch (type_)
+  {
+  case ipv4:
+    return ipv4_address_.is_unspecified();
+  case ipv6:
+    return ipv6_address_.is_unspecified();
+  default:
+    return false;
+  }
 }
 
 bool address::is_multicast() const
 {
-  return (type_ == ipv4)
-    ? ipv4_address_.is_multicast()
-    : ipv6_address_.is_multicast();
+  switch (type_)
+  {
+  case ipv4:
+    return ipv4_address_.is_multicast();
+  case ipv6:
+    return ipv6_address_.is_multicast();
+  default:
+    return false;
+  }
 }
 
 bool operator==(const address& a1, const address& a2)
 {
   if (a1.type_ != a2.type_)
     return false;
+  if (a1.type_ == address::ipv4)
+    return a1.ipv4_address_ == a2.ipv4_address_;
   if (a1.type_ == address::ipv6)
     return a1.ipv6_address_ == a2.ipv6_address_;
-  return a1.ipv4_address_ == a2.ipv4_address_;
+  return true;
 }
 
 bool operator<(const address& a1, const address& a2)
@@ -206,9 +241,11 @@
     return true;
   if (a1.type_ > a2.type_)
     return false;
+  if (a1.type_ == address::ipv4)
+    return a1.ipv4_address_ < a2.ipv4_address_;
   if (a1.type_ == address::ipv6)
     return a1.ipv6_address_ < a2.ipv6_address_;
-  return a1.ipv4_address_ < a2.ipv4_address_;
+  return false;
 }
 
 } // namespace ip