Macro hints

I

inftoconc

Hi, I came across the macro definition (below) to read 16 bits out of
a buffer into an integer. b's type is byte.

#define READ16(b) ((*(b)<<8) | *((b)+1))

I can't quite figure out how it works. Any hints would be appreciated.
Thanks!
 
A

Army1987

Hi, I came across the macro definition (below) to read 16 bits out of
a buffer into an integer. b's type is byte.

#define READ16(b) ((*(b)<<8) | *((b)+1))

I can't quite figure out how it works. Any hints would be appreciated.
Thanks!

*(b)<<8 is *(b) (i.e. b[0]) shifted by eight bits to the left,
i.e. b[0] * 256.
(b[0] << 8) | b[1] is the bitwise or of its operands, which in
this case is their sum. So that macro is essentially equivalent
(assuming CHAR_BIT is 8) to
#define READ16(b) (256 * (b)[0] + (b)[1])
 
R

Richard

Hi, I came across the macro definition (below) to read 16 bits out of
a buffer into an integer. b's type is byte.

#define READ16(b) ((*(b)<<8) | *((b)+1))

I can't quite figure out how it works. Any hints would be appreciated.
Thanks!

Evaluate it left to right.

It takes the byte at address b (*b) and then shifts the result left 8
bits (<<8). It then bitwise ors (|) the byte stored at the address B
points to offset by one byte.

I'm not sure if I should have been saying char above instead of byte :-;

It's to guarantee a 16 bit value from the buffer into an integer or
bigger with no endian conversions.
 
D

Duncan Muirhead

Evaluate it left to right.

It takes the byte at address b (*b) and then shifts the result left 8
bits (<<8). It then bitwise ors (|) the byte stored at the address B
points to offset by one byte.

I'm not sure if I should have been saying char above instead of byte :-;
<snip>
You should say byte. The macro will only work if bytes are unsigned.
If chars are signed, and b is a char*, the macro goes horribly wrong when
b[1] is negative.
 
R

Richard

Duncan Muirhead said:
Evaluate it left to right.

It takes the byte at address b (*b) and then shifts the result left 8
bits (<<8). It then bitwise ors (|) the byte stored at the address B
points to offset by one byte.

I'm not sure if I should have been saying char above instead of byte :-;
<snip>
You should say byte. The macro will only work if bytes are unsigned.
If chars are signed, and b is a char*, the macro goes horribly wrong when
b[1] is negative.

Who has a link to a concise definition of C and sizes of bits, bytes,
chars, or "how to talk portable C" etc preferably not the standard which
I find almost unreadable in most cases.
 
S

santosh

Richard said:
Duncan Muirhead said:
(e-mail address removed) writes:

Hi, I came across the macro definition (below) to read 16 bits out of
a buffer into an integer. b's type is byte.

#define READ16(b) ((*(b)<<8) | *((b)+1))

I can't quite figure out how it works. Any hints would be appreciated.
Thanks!


Evaluate it left to right.

It takes the byte at address b (*b) and then shifts the result left 8
bits (<<8). It then bitwise ors (|) the byte stored at the address B
points to offset by one byte.

I'm not sure if I should have been saying char above instead of byte :-;
<snip>
You should say byte. The macro will only work if bytes are unsigned.
If chars are signed, and b is a char*, the macro goes horribly wrong when
b[1] is negative.

Who has a link to a concise definition of C and sizes of bits, bytes,
chars, or "how to talk portable C" etc preferably not the standard which
I find almost unreadable in most cases.

Annex J of the Standard.
http://home.att.net/~jackklein/c/inttypes.html
http://nob.cs.ucdavis.edu/bishop/papers/1986-cjourv1n4/port.ps
http://www.cpax.org.uk/prg/portable/c/index.php
 
O

Old Wolf

It takes the byte at address b (*b) and then shifts the result left 8
bits (<<8). It then bitwise ors (|) the byte stored at the address B
points to offset by one byte.

Well it could do those in either order (but the
result would be the same in either case).
It's to guarantee a 16 bit value from the buffer into
an integer or bigger with no endian conversions.

It guarantees to read it in a big-endian fashion,
i.e. b[0] is the MSB and b[1] is the LSB.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top