0

I am a beginner in C and During Programming I have found this code about bitwise addition

#define WORD_FROM_BUF(WRD) ((((unsigned char *)(WRD))[0]<<8)|((unsigned char *)(WRD))[1])

I have tried to modify this code to this form

 #define WORD_FROM_BUF(WRD) (((unsigned char *)(WRD[0])<<8)|((unsigned char *)(WRD[1]))

EDIT My problem is similar to these 2 questions C macros and use of arguments in parentheses- by Palec

Can we remove parentheses around arguments in C macros definitions?- by Palec

Thanks everyone for your explanations

  • 2
    Two words: operator precedence. – John Bollinger Dec 16 '21 at 22:09
  • Does this answer your question? [C macros and use of arguments in parentheses](https://stackoverflow.com/questions/7186504/c-macros-and-use-of-arguments-in-parentheses) – Brian61354270 Dec 16 '21 at 22:10
  • 3
    Ugh. IMO that's really bad code. Waaaay too much is crammed into that macro - which is why you're having problems figuring out what's going on. It's screaming to be replaced by a function that gets inlined during optimization... – Andrew Henle Dec 16 '21 at 22:14
  • 2
    What is your objective in modifying the original code, anyway? Random rearrangements of symbols in the source should be expected generally to lead to different results (often compilation errors, but sometimes differently-working valid programs). – John Bollinger Dec 16 '21 at 22:14
  • 1
    Apart from the second example having unbalanced parentheses, the casts in the first example modify `WRD` (before indexing the result) but in the second they modify `WRD[0]` and `WRD[1]` (after indexing the pointer). The actual offset of index `[1]` in bytes depends on the type of the pointer. – Weather Vane Dec 16 '21 at 22:43
  • I was only trying to see the result of changing the original code, as it seemed strange to me to put the original declaration between parentheses (WRD). and when I saw the error in the second code I did not understand why this happened. – Ayman hussien Dec 17 '21 at 10:57

1 Answers1

1

(unsigned char *)(WRD) takes the pointer(?) WRD and converts it into a pointer to bytes. Indexing that byte-pointer with [0] gets the first byte from the buffer. When combining that with the next byte, you get a two-byte value.

(unsigned char *)(WRD[0]) takes the first word(?) from the buffer and turns that word into a pointer. Totally different, and very likely totally wrong as shifting the pointer << 8 make little sense.

Then WRD[1] picks up the second word from the buffer, not the second byte.

BoP
  • 2,310
  • 1
  • 15
  • 24