# Gather all IP addresses of a host as a vector

I have the following working code to get IPv4/v6 addresses from host names:

#include <array>
using std::array;

#include <iostream>
using std::cout;

#include <netdb.h>

#include <stdexcept>
using std::domain_error;

#include <sys/socket.h>

#include <string>
using std::string;

#include <vector>
using std::vector;

#include <boost/asio.hpp>

{
struct addrinfo req = {.ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM};
int error = getaddrinfo(hostname.c_str(), nullptr, &req, &pai);
if (error)
throw domain_error("Could not resolve host name.");

for(struct addrinfo *info = pai; info != nullptr; info = info->ai_next) {
if (info->ai_family == AF_INET) {
} else {
array<unsigned char, 16> bytearray = {
};
}
}

}

int main()
{

cout << "Address: " << ipa << "\n";

return 0;
}


I find the conversion fom uint8_t[16] (ipv6socket->sin6_addr.s6_addr) to std::array<unsigned char, 16> a bit verbose. I also considered doing it in a for-loop, but this would still seem cumbersome to me, somehow. I tried static_cast and reinterpret_cast to no avail. Is there a possibility to do this conversion in a simpler way, preferably a one-liner?

• You object to a for loop, would you object to std::copy or something similar? May 20 at 11:29
• I would not. I am explicitely looking for alternatives. May 20 at 11:31

I agree with you that the copying of data from s6_addr seems cumbersome. I would instead just cast without copying:

auto& bytearray = reinterpret_cast<std::array<unsigned char,16>&>(ipv6socket->sin6_addr.s6_addr);


(If we had needed to copy, we could change auto& to plain auto).

Apart from this, the variable ipv6base is never used, so should just be removed.

• Thank you so much. Such a noob mistake from me. I forgot the ampersands. :facepalm: May 20 at 13:50
• Oh, I've done the same myself from time to time. Easy to get wrong, and very hard to spot what's incorrect! May 20 at 14:08
• Using a type-change cast like that, with modern compilers you have to beware of undefined behavior. The old tricks using a union or type puns are now technically illegal. How is this not falling into that trap? May 20 at 14:11
• Good point @JDługosz. I can't prove that this is legal. I think it's likely to be safe in this context. May 20 at 14:14
• en.cppreference.com/w/cpp/language/reinterpret_cast "Whenever an attempt is made to read or modify the stored value of an object of type DynamicType through a glvalue of type AliasedType, the behavior is undefined unless one of the following is true: ... AliasedType is std::byte, char, or unsigned char: this permits examination of the object representation of any object as an array of bytes." May 20 at 14:21