To understand a C code about endianness
-
18-09-2019 - |
Question
I am studying big and little-endianness.
1. What is the purpose of | \
in the following code?
...
#elif defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
#define htons(A) ((((uint16_t)(A) & 0xff00) >> 8) | \
(((uint16_t)(A) & 0x00ff) << 8))
...
2. What is the purpose of (A)
in the code?
Solution
The '|' is the bitwise OR operator. It basically combines the values. The 'A' is the parameter from the #define htons. It is enclosed in parentheses so that expressions will not confuse the programmer or compiler. The '\' continues the macro onto the next line. (A macro usually ends at the end of the line.)
This macro takes the 16-bit value in A and masks out the top 8 bits. It then takes that value and shifts it right 8 bits. That means the top 8 bits are now on the bottom of the 16-bit value. It next masks out the top 8 bits of the original value in A and shifts those left 8 bits. That means the bottom 8 bits are now on the top. Finally, it recombines the two values back into one value.
The end result is that the top and bottom bytes have had their places swapped.
OTHER TIPS
This code is nothing more than standard C-preprocessor Macros.
The |
is the bitwise OR operator. The \
escapes the newline so that the #define
can continue to the next line. The (A)
is a parameter for the macro.
| performs a bitwise "OR" on two integers \ is an escape character that allows a #define to cotninue onto the next line
It's a macro, it'll get expanded when you uses it.
If you e.g. use("call") the macro as
uint16_t i = htons(0x1234);
It will expand to:
uint16_t i = ((((uint16_t)(0x1234) & 0xff00) >> 8) |(((uint16_t)(0x1234) & 0x00ff) << 8));
It's not that unlike a variable in a function, e.g.
uint16_t htons(uint16_t A)
{
return (A & 0xff00) >> 8) | (A & 0x00ff) << 8);
}