experimenting with unions - byteswap approach..

M

ma740988

Consider the source snippet:

union to_uchar
{
int i;
unsigned int ui;
long l;
unsigned long ul;
short s;
unsigned short us;
double d;
unsigned char uc[8];

void byteSwap(int siz)
{
int idx = 0;
int jdx = siz-1;
while (idx < jdx)
{
std::swap(uc[idx], uc[jdx]);
idx++, jdx--;
}
}
to_uchar(int ii) : i(ii) { swap(i); }
to_uchar(double dd) : d(dd) { swap(d); }
unsigned char* getBuf() { return uc; }

static void swap(int& i)
{
to_uchar x = i; //[1]
x.byteSwap(sizeof(i));
i = x.i;
}
static void swap(double& d)
{
to_uchar x = d; //[2]
x.byteSwap(sizeof(d));
d = x.d;
}

};


int main()
{
double d = 12345.678;
to_uchar::swap(d);
int i = 12345;
to_uchar::swap(i);

to_uchar iuc(12345);
unsigned char* bufi = iuc.getBuf();
to_uchar duc(12345.678);
unsigned char* bufd = duc.getBuf();
}

the lines indicated by [1] and [2] above results in exceptions but this
is one of those cases where I dont fully understand why or what teh
solution is.

Thanks in advance
 
D

David Hilsee

Consider the source snippet:

union to_uchar
{
int i;
unsigned int ui;
long l;
unsigned long ul;
short s;
unsigned short us;
double d;
unsigned char uc[8];

void byteSwap(int siz)
{
int idx = 0;
int jdx = siz-1;
while (idx < jdx)
{
std::swap(uc[idx], uc[jdx]);
idx++, jdx--;
}
}
to_uchar(int ii) : i(ii) { swap(i); }
to_uchar(double dd) : d(dd) { swap(d); }
unsigned char* getBuf() { return uc; }

static void swap(int& i)
{
to_uchar x = i; //[1]
x.byteSwap(sizeof(i));
i = x.i;
}
static void swap(double& d)
{
to_uchar x = d; //[2]
x.byteSwap(sizeof(d));
d = x.d;
}

};


int main()
{
double d = 12345.678;
to_uchar::swap(d);
int i = 12345;
to_uchar::swap(i);

to_uchar iuc(12345);
unsigned char* bufi = iuc.getBuf();
to_uchar duc(12345.678);
unsigned char* bufd = duc.getBuf();
}

the lines indicated by [1] and [2] above results in exceptions but this
is one of those cases where I dont fully understand why or what teh
solution is.

I'm not sure what you're trying to do here, but your constructors are a
little screwy, and it has nothing to do with unions.

This constructor...

to_uchar(int ii) : i(ii) { swap(i); }

calls void to_uchar::swap(int& i)...

to_uchar x = i; //[1]

which constructs a to_uchar from an int (invokes the to_uchar(int ii)
constructor)...

to_uchar(int ii) : i(ii) { swap(i); }

which calls void to_uchar::swap(int& i)...

to_uchar x = i; //[1]

which constructs a to_uchar from an int (invokes the to_uchar(int ii)
constructor)...

I think you can see where this is going (infinite recursion). It looks like
the other constructor suffers from the same problem.
 
M

Maxim Yegorushkin

(e-mail address removed) wrote:

[]
int main()
{
double d = 12345.678;
to_uchar::swap(d);
int i = 12345;
to_uchar::swap(i);

to_uchar iuc(12345);
unsigned char* bufi = iuc.getBuf();
to_uchar duc(12345.678);
unsigned char* bufd = duc.getBuf();
}

Why don't you use std::reverse()?

template<class T>
void byteswap(T* t)
{
std::reverse(reinterpret_cast<char*>(t), reinterpret_cast<char*>(t
+ 1));
}

By the way, you can't byteswap a floating point number (float, double,
....), since not any bit pattern is a valid floating point number binary
representation.
 
M

ma740988

|| By the way, you can't byteswap a floating point number (float,
double,
|| ...), since not any bit pattern is a valid floating point number
binary
|| representation.

Maxim, thanks for the suggestion.... So what do you do with floats
(doubles) when you have endian issues across platforms? IOW the
sender transmits - say 9.2 and the receiver sees some convoluted number.
 
M

Maxim Yegorushkin

|| By the way, you can't byteswap a floating point number (float,
double,
|| ...), since not any bit pattern is a valid floating point number
binary
|| representation.

Maxim, thanks for the suggestion.... So what do you do with floats
(doubles) when you have endian issues across platforms? IOW the
sender transmits - say 9.2 and the receiver sees some convoluted number.

I use some binary format and a library, such as XDR.

Alternatively, you may extract mantissa and exponent as integers, send
and reassemble the number on the receiving side.
 
M

ma740988

Ironically, you brought this up becasue serilization is the approach
used.
I need to delve more into the text 'approach' so I suspect I'll peruse
the web to get a feel for how this all works (somebody should have
something that shows this).

Being a little more than an intermediate apprentice :) it'll take me a
few to get this right.

Thanks
 
M

mlimber

Ironically, you brought this up becasue serilization is the approach
used.
I need to delve more into the text 'approach' so I suspect I'll peruse
the web to get a feel for how this all works (somebody should have
something that shows this).

Being a little more than an intermediate apprentice :) it'll take me a
few to get this right.

Thanks

You might also want to consider using the Boost serialization library:

http://boost.org/libs/serialization/doc/index.html

Cheers! --M
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,153
Latest member
NamKaufman
Top