Is there any standard htonl-like function for 64 bits integers in C++?
You are probably looking for bswap_64
I think it is supported pretty much everywhere but I wouldn't call it standard.
You can easily check the endianness by creating an int with a value of 1, casting your int's address as a char*
and checking the value of the first byte.
For example:
int num = 42;
if(*(char *)&num == 42)
{
//Little Endian
}
else
{
//Big Endian
}
Knowing this you could also make a simple function that does the swapping.
You could also always use boost which contains endian macros which are portable cross platform.
Portable way of sending 64-bit variable through POSIX socket
You can just apply htonl()
twice, of course:
const uint64_t x = ...
const uint32_t upper_be = htonl(x >> 32);
const uint32_t lower_be = htonl((uint32_t) x);
This will give you two 32-bit variables containing big-endian versions of the upper and lower 32-bit halves of the 64-bit variable x
.
If you are strict POSIX, you can't use uint64_t
since it's not guaranteed to exist. Then you can do something like:
typedef struct {
uint32_t upper;
uint32_t lower;
} my_uint64;
And just htonl()
those directly, of course.
converting 64 bit int from host to network order in c, i get only zeros
void nw_order(const union u *host, union u *net)
{
net -> u32[0] = htonl(net->u32[1]);
net -> u32[1] = htonl(net->u32[0]);
}
You are only using the pointer to net here:
This sets the low 4 bytes to the byte-reversed high 4 bytes and the high four bytes to the twice byte-reversed high 4 bytes <=> to their previous content.
Not what you wanted, right?
Anyway, better do it thus:
uint64_t nw_order(const uint64_t in) {
unsigned char out[8] = {in>>56,in>>48,in>>40,in>>32,in>>24,in>>16,in>>8,in};
return *(uint64_t*)out;
}
This has two advantages:
- Also works on big-endian (You might not care, if you are only on x86)
- Does not needlessly use pointers.
Also consider that random()
only returns an int
, and does not use the full range: Check RAND_MAX
. Anyway, this function is not of reliable quality for anything but quick joke-programs.
Using htons() in my code puts all zeros in the buffer and I don't understand why
Converting endianess of a 16 bit number and storing it in a byte array is trivial, there is no need for library functions. Assuming 32 bit CPU:
uint16_t u16 = ...;
uint8_t out[2];
out[0] = ((uint32_t)u16 >> 8) & 0xFFu;
out[1] = ((uint32_t)u16 >> 0) & 0xFFu;
The casts and u
suffix are there as a good habits to block implicit promotion to int
which is problematic in some cases, since it's a signed number.
Since shifts don't care about the underlying endianess, the above code works for both big-to-little and little-to-big conversions, as long as you go from one to the other.
This scales to 32 bit types as:
uint32_t u32 = ...;
uint8_t out[4];
out [0] = ((uint32_t)u32 >> 24) & 0xFFu;
out [1] = ((uint32_t)u32 >> 16) & 0xFFu;
out [2] = ((uint32_t)u32 >> 8) & 0xFFu;
out [3] = ((uint32_t)u32 >> 0) & 0xFFu;
Is there any conversions when storing/reading integers of different size to/from union?
So is it legal in C++?
No, it isn't legal in c++ (Wikipedia also already stated "While not allowed by C++ ...").
In c++ a union
is just reserving memory for the contained union
members, such that it is enough to fit the largest member. That memory is shared by all members.
Accessing a different member from the union as was used to initialize it, is undefined behavior. You need to decide beforehand with which union
members to work, if these are shared by any functions (this is often done using a type discriminator).
Related Topics
Gmon.Out Is Not Written After Compiling with Gcc -Pg -G
What Exif Lib How to Use from a Qt Program (On Embedded Linux)
How to Avoid Multiple Definition Linking Error
Find Argc and Argv from a Library
Openprocess/Readprocessmemory/Writeprocessmemory/Closehandle Equivalent
Press Anykey to Continue in Linux C++
C++ Portability Between Windows and Linux
Way Cross Compile C/C++ Code to Run on Windows, Linux, and MAC Os
Cannot Get Makefile to Build Each Object from Its Corresponding Source
Missing Lboost_Thread-Mt in Mongodb Cpp Driver (Ubuntu Server X64)
Using Input Function in C on Linux, Without Pressing Enter
C++ Fast Screenshots in Linux for Use with Opencv
What Are the Rules for the "..." Token in the Context of Variadic Templates