-
bit fields and union
Hi everyone,
Just a quick question. If I make my code like this:
Code:
typedef struct{
unsigned long btfd1:8;
unsigned long btfd2:8;
unsigned long btfd3:8;
unsigned long btfd4:8;
} a;
typedef union{
a union_btfd;
unsigned long con;
} b;
int main(void)
{
...
a structBT;
b hold;
b temp;
hold.union_btfd = structBT;
temp.con = htonl(hold.con);
structBT = temp.union_btfd;
return 0;
}
Would this actually work as I think it will? Meaning will the union also apply the htonl() function to struct a? I tried it but I'm still not so sure if I'm correct.
Thanks.
-
What you suggest will work - but not reliably in a multi-architecture environment, unfortunately.
Bitfields are implementation dependant, so the order in one machine and the order in another machine may not match (using either different compilers or different processor with the same compiler [1]).
It will work fine as long as you have the same compiler and the same processor architecture at both ends. But then you wouldn't, technically, need HTONL either.
In your example, an array of 4 (unsigned) char could be used, but if you have bitfields that are not 8, 16, 32 or 64 bits wide, then you will have to write the code to extract (using & and >> operators) and set (using | and << operators) the different fields.
[1] By different processor, I don't mean an x86 from AMD Athlon vs. x86 Intel Core 2 or similar, but different processor architectures, such as x86, Alpha, Sparc, MIPS, ARM, Itanium, etc.
--
Mats
-
Thanks matsp.
I knew it was too easy to work. I was really hoping for a work around using htonl() and etc but from what I understand it converts by blocks rather than converting bit by bit (kindly correct me if I'm wrong).
Actually, that is exactly my problem with the bit fields I have, they have varying bit field widths. So, just a confirmation, is there no work around to my problem? And do I have to extract and rearrange the bit fields bit by bit so to speak?
Again thanks.
-
The only deterministic way of transporting bitfields over a network is that you order them in strict order yourself, yes. Or of course, using text-fields, e.g:
Code:
struct bf
{
unsigned a1:4;
unsigned a2:5;
unsigned a3:7;
unsigned a4:16;
};
struct bf a = { 11, 17, 97, 4127 };
can be sent as: "11,17,97,4127" (obviously, comma is just one example of separator).
It takes a bit more space, and requires parsing to get it back, but it's not terribly complex - and it's definitely "safe", with no order difference whatsoever.
--
Mats
-
Okay, will try what you suggested.
Kind of weird to ask for a confirmation but I really wanted to be sure. You see I'm working on a porting project that states in its documents that I should use htonl() on the bit fields in order to convert it. But, as you now know, I wasn't too keen that it was possible. At least now, I've got another's opinion.
Thanks.