DiBosco
DiBosco

Reputation: 876

What do these macros do?

I have inherited some heavily obfuscated and poorly written PIC code to modify. There are two macros here:

#define TopByteInt(v) (*(((unsigned char *)(&v)+1)))
#define BottomByteInt(v) (*((unsigned char *)(&v)))

Is anyone able to explain what on earth they do and what that means please?

Thanks :)

Upvotes: 5

Views: 151

Answers (3)

Tom Tanner
Tom Tanner

Reputation: 9354

Ugg.

Assuming you are on a little-endian platform, that looks like it might meaningfully be recorded as

#define TopByteInt(v) (((v) >> 8) & 0xff)
#define BottomByteInt(v) ((v) & 0xff)

It is basically taking the variable v, and extracting the least significant byte (BottomByteInt) and the next more significant byte (TopByteInt) from that. 'TopByte' is a bit of a misnomer if v isn't a 16 bit value.

Upvotes: 1

dfranca
dfranca

Reputation: 5322

(*((unsigned char *)(&v)))

It casts the v (a 16 bit integer) into a char (8 bits), doing this you get only the bottom byte.

(*(((unsigned char *)(&v)+1)))

This is the same but it gets the address of v and sum 1 byte, so it gets only the top byte.

It'll only work as expected if v is a 16 bits integer.

Upvotes: 1

unwind
unwind

Reputation: 399813

They access a 16-bit integer variable one byte at a time, allowing access to the most significant and least significant byte halves. Little-endian byte order is assumed.

Usage would be like this:

uint16_t v = 0xcafe;
const uint8_t v_high = TopByteInt(&v);
const uint8_t v_low  = BottomByteInt(&v);

The above would result in v_high being 0xca and v_low being 0xfe.

It's rather scary code, it would be cleaner to just do this arithmetically:

#define TopByteInt(v)    (((v) >> 8) & 0xff)
#define BottomByteInt(v) ((v) & 0xff)

Upvotes: 5

Related Questions