First problem: don't rely on short
and long
sizes being respectively 16 and 32 bit.
Use stdint.h
include which defines uint16_t
and uint32_t
Second problem: protect your term with parentheses because you could pass some expression to the macros.
For instance REVERSE_SHORT(4000<<3)
would yield 0 because of operator precedence. What you cannot avoid is the multiple computation of n
expression (maybe the optimizer can help but that's not guaranteed)
To sum it up I would write them as:
#include <stdint.h>
#define REVERSE_UINT16(n) ((uint16_t) ((((n) & 0xFF) << 8) | \
(((n) & 0xFF00) >> 8)))
#define REVERSE_UINT32(n) ((uint32_t) ((((n) & 0xFF) << 24) | \
(((n) & 0xFF00) << 8) | \
(((n) & 0xFF0000) >> 8) | \
(((n) & 0xFF000000) >> 24)))
Which doesn't mean it's safe to side-effect expressions like n++
or result from function calls, as someone noted in comments. Only the fact that it's written in uppercase could remind users to avoid side-effect expressions.