1

I use the next way to get the byte representation of numbers in C++:

template< class T > union u_value { T value; unsigned char bytes[ sizeof( T ) ]; } 

Please, tell me is that the true way? And if not why and how should I get it?

4 Answers 4

3

There is no "true" way. What you did is one way to do it. Generally speaking, stuff like this is discouraged as it usually results in non-portable code. Sometimes there are good reasons for poking internals like that, but since you didn't tell what you're about to do with the "byte representation", there's little we can do to judge if this approach is appropriate.

Edit: So networking is your subject here. In this case, either:

  1. You are transferring POD types only (char, short, int, the likes). In this case, you might want to look into <netinet/in.h>, where you'll find the macros htons(), htonl(), ntohs() and ntohl(), which do host-to-network-byte-order and vice versa for you.

  2. You are transferring complex types (e.g. classes). In this case, you might want to look into Boost Serialization, because there's much more to be considered here than mere byte order.

Either way, it is advisable to use ready-made, well-documented and -understood code, instead of doing byte-juggling yourself.

Sign up to request clarification or add additional context in comments.

4 Comments

I need to get the array of bytes of different fundumental types.
@emzar: In general, te other side of the wire may not have the same representation. i.e. the bytes 0x0, 0x42 may be 0x0042 on one side and 0x4200 on the other. That's why we call this non-portable.
@MSalters: Oh I see, the endianness of the transfering array is described by the protocol. I convert it, if nessessary. And they have to convert the array to their endiannes on the other wire, if nessesary.
@emzar: That's one of the issues. Another is just plain size (how big is an int ?) and there's also the question how you encode floating-point types. Could be more I'm overlooking.
1

Not true way. This way is not portable and often may result in undefined behavior. Because,

  1. Padding (done by compiler) is ignored
  2. virtual function extra space is not taken care visibly (if T is polymorphic)

4 Comments

I use it only for the fundumental types. And I can write the wrapper for the {little,big}-endian systems for the portability.
+1, not true way. One minor nit: Change "may result in undefined behavior" to "is undefined behavior". Assigning one member of a union and then retrieving another member is undefined behavior.
@David Hammen: I see, thx, but I can't find this info in Standard.
@emzar: "In a union, at most one of the data members can be active at any time, that is, the value of at most one of the data members can be stored in a union at any time." You are looking at your u_value as having both the value member and bytes member simultaneously available. They aren't. The condoned use of unions in C++ involves setting a particular member and then retrieving only that specific member. If you later set some other member, you should once again retrieve only that specific member. Retrieving a member other than the one that was most recently assigned is UB.
0

If you are transferring the bytes across the network you need to be careful about the Endianess

1 Comment

Yeap, I know, and it's simple to convert to big or little-endian.
0

This will work. Just be sure that anything with virtual functions, pointers and so on won't be accurate next time you deserialize them.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.