Reputation: 14256
Why name a union if the compiler always treats the object as anonymous, regardless as to whether or not the union is named?
My implementation looks like this:
typedef struct _DMessageHeader {
union _msgId {
unsigned char ucMsgId;
unsigned short usMsgId;
unsigned long ulMsgId;
unsigned long long ullMsgId;
} msgId;
} DMSG_HDR, *PDMSG_HDR;
I'd like to be able to access it like this, but the compiler throws an error:
PDMSG_DESC ptMsg->hdr.msgId = id_in;
It only allows me to directly access the union member like this:
PDMSG_DESC ptMsg->hdr.msgId.ucMsgId = id_in;
Any thoughts as to why this is, or how I may access the union by name?
Upvotes: 1
Views: 122
Reputation: 8926
Because you're not using an anonymous union in your example. You've given your union member of your struct a name, msgId
, and it has members. You can't assign directly to the union itself, you have to assign to a member of the union.
An anonymous union would be as follows:
union {
int i;
char c;
};
i = 1;
or
struct s
{
int i1;
union {
int i2;
char c2;
};
};
s s1.i2 = 5;
The union in struct s has no name, and it's members are accessed directly.
ETA:
Assuming your variable id_in
is an unsigned char
since you assign it to the unsigned char member in the example that works, why would you expect this to work?
PDMSG_DESC ptMsg->hdr.msgId = id_in;
ptMsg->hdr.msgId
is not of type unsigned char
nor is it an implicitly convertible type. ptMsg->hdr.msgId
is of type _DMessageHeader::_msgId
.
"A union is a special class type that can hold only one of its non-static data members at a time." (http://en.cppreference.com/w/cpp/language/union) It's a class type and you've defined no conversion operators or constructors. Of course it won't allow the assignment.
Upvotes: -1
Reputation: 21
Its a type thing. The compiler can't convert an int something to a union. You can however overload the "=" operator to do it.
Upvotes: 2
Reputation: 62
I'm not sure why would you use union in this case at all. Please note that the size of the struct is 8 bytes (size of long long) on my 64bit machine.
#include <iostream>
using std::cout;
using std::endl;
typedef struct _DMessageHeader {
union _msgId {
unsigned char ucMsgId;
unsigned short usMsgId;
unsigned long ulMsgId;
unsigned long long ullMsgId;
} msgId;
} DMSG_HDR, *PDMSG_HDR;
int main( int argc , char ** argv, char ** env)
{
cout<<"sizof DMessageHeader"<<sizeof(DMSG_HDR)<<endl;
return 0;
}
If all you store in union msgid is a single id of varying length (1 - 8) bytes depending on your architecture) and you have no memory constrains rewrite your struct as following:
typedef struct _DMessageHeader {
unsigned long long msgId;
} DMSG_HDR, *PDMSG_HDR;
DMSG_HDR hdr;
hdr.msgId = id_in;
Also I suggest reading this thread for thorough discussion about using unions in C++.
Upvotes: 1
Reputation: 18825
There can be various reasons:
Upvotes: -1