Initializing a union
Previous code :
struct Inet_address{
char v4[4];
};
extern "C" Inet_address Inet_loopback =
{
{127,0,0,1}
};
After modifying:
I have made Inet_address a union Here Inet address is a union
union Inet_address{
char v4[4];
char v6[16];
};
Now I want to do the same operation on extern "C" Inet_address Inet_loopback Say,
extern "C" Inet_address Inet_loopback =
{
if(some condition)
{127,0,0,1} //It should be Inet_address.v4
else
{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } //This should 开发者_JS百科be Inet_address.v6
};
Please suggest a correct way to acheive this as I am getting error here.
You shouldn't use char arrays for this - make a union out of in_addr
and in6_addr
:
typedef union {
struct in_addr inaddr;
struct in6_addr in6addr;
} in46_addr_t;
To set an ipv4 loopback address:
addr.inaddr.s_addr = INADDR_LOOPBACK;
For IPv6:
addr.in6addr = in6addr_loopback; // pre-defined global variable (note: assumes linux socket API)
bdonlan's answer is good, but if you want something totally POSIXly portable, see getaddrinfo(). (Well, modern POSIX, anyway.)
struct addrinfo hints = { 0 };
hints.ai_family = AF_INET6;
hints.ai_flags = AI_NUMERICHOST;
struct addrinfo *result = NULL;
getaddrinfo("::1", NULL, &hints, &result);
// result[0].ai_addr is now a pointer to the localhost IPv6 address as a sockaddr_in6
// struct.
freeaddrinfo(result);
In my opinion it does not make sense to have such union, since Inet_address
would take in memory the size of the biggest array. Why don'y you use only one array of 16 elements ? Furthermore, you will have to put your initialization in a function if your condition can only be evaluated during runtime. If your condition can be evaluated during compile time, may be what you try to do could be achieved using templates and metaprogramming, but it won't be simple and it may be hardly readable.
Could you tell us more about your condition ?
Since you are (apparently, judging by the tags attached to this question) using c++ for this project, you should not use a union at all. C used unions as a sort of primitive polymorphism. In c++ inheritance is available, and is a much more robust method of implementing polymorphism.
I would recommend that you use a small inheritance heirarchy for this: ( Note: this is skeleton code that is only meant to give you an idea of how this might work)
class Inet_address
{
vector<int> _address;
public:
Inet_address();
virtual ~Inet_address();
// pure virtual function...special behavior implemented in sub classes
virtual vector<int> loopback() = 0;
}
class Inet_address_v4 : public Inet_address
{
public:
Inet_address_v4();
virtual ~Inet_address_v4();
// special behavior for v4
virtual vector<int> loopback();
}
class Inet_address_v6 : public Inet_address
{
public:
Inet_address_v6();
virtual ~Inet_address_v6();
// special behavior for v6
virtual vector<int> loopback();
}
int main()
{
// Create a new v4 address object
Inet_address* my_v4_addr = new Inet_address_v4();
// Create a new v6 address object
Inet_address* my_v6_addr = new Inet_address_v6();
vector<Inet_address*> addresses;
addresses.push_back( my_v4_addr );
addresses.push_back( my_v6_addr );
// The loopback function is called in the same way for both sub-classes
for( unsigned int i=0; i<addresses.size(); i++ )
{
Inet_address* curr_adr = addresses[i];
curr_addr->loopback();
}
return 0;
}
This approach is generally the standard method used in c++. It is a really powerful approach, because it can allow you to create many different types of objects with similar behavior that can all be manipulated using the exact same function calls.
See this for an overview of c++ inheritance: http://www.cplusplus.com/doc/tutorial/inheritance/
Good luck!
精彩评论