Regarding operator precedence, I'd suggest you first take a look to this table.
Now, the ++/--
can be tricky operators because you need to identify whether they're prefix or postfix operators, as you can see in the table if they were prefix ones they'd have the same precedence than *
(Dereference).
So, let's analize what's going with your last line len = (u16)*ptr++ <<8 | *ptr++;
, there is this set of operators {=, (cast), *(dereference), ++(postfix), <<, |}
, so the order of evaluation according to this table would be ++(postfix), *dereference, (type), <<, |, =
That'd be regarding to the order of evaluation, but you need to consider:
Postfix increment/decrement have high precedence, but the
actual increment or decrement of the operand is delayed (to be
accomplished sometime before the statement completes execution).
That said, here's a couple of ways to achieve what you want:
ptr[1]<<8 | ptr[2]
or:
*(ptr+1) <<8 | *(ptr+2)
One last advice, be careful when you're dealing with operators with the same precedence, as you can see in the table, the associativity could be either left-to-right or right-to-left.
PS: Of course, the asm code generated will depend by the compiler & config used, here's an example of vs2015 in debug mode of that line:
; 7 : u16 len = (u16)*ptr++ <<8 | *ptr++;
mov ecx, DWORD PTR _ptr$[ebp]
movzx edx, BYTE PTR [ecx]
shl edx, 8
mov eax, DWORD PTR _ptr$[ebp]
movzx ecx, BYTE PTR [eax]
or edx, ecx
mov WORD PTR _len$[ebp], dx
mov edx, DWORD PTR _ptr$[ebp]
add edx, 1
mov DWORD PTR _ptr$[ebp], edx
mov eax, DWORD PTR _ptr$[ebp]
add eax, 1
mov DWORD PTR _ptr$[ebp], eax
Happy coding.