Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Some parts of this C code doesn't make sense for me

Tags:

c

Hi considering this code:

uint16_t dest_pid;
uint8_t *p;

pf->dest_pid = p[0] + (p[1] << 8)   //(p[1] << 8) equals 0 right?

This code is a part of embedded operating system's driver. Some ideas what might be the idea behind that statement? Or may be I am missing something essential?

like image 423
Radoslaw Krasimirow Avatar asked Aug 27 '15 11:08

Radoslaw Krasimirow


2 Answers

I assume that your p is meaningfully initialized (to point to some valid location).

Then in p[0] + (p[1] << 8) the p[1] would be implicitly promoted to unsigned before doing the left shift << 8, so the code does make sense (e.g. on 32 bits processors like ARM). Informally it makes a 16 bit number whose lower 8 bits are from p[0] and higher 8 bits are from p[1]

Grossly speaking, the implicit rule is that in C arithmetic operations are on int at least (and never on smaller pieces of data like short or uint8_t or char). But the details are more complex (and have slightly evolved from C89 to C99 and to C11 standards).

like image 170
Basile Starynkevitch Avatar answered Nov 15 '22 09:11

Basile Starynkevitch


First: dest_pid after pf is part from structure and I think it is another variable then uint16_t dest_pid;

Second: p is a pointer to uint8_t, when you do (p[1] << 8) you shift what is inside the pointer by 8, for example if p[1] = 0xE5 after shifting it will be 0xE500. Remember that you put your result in dest_pid which is a 2 bytes variable.

The translation of the last line is most likely to take the low byte (less significant) of pid and add it to the high byte(shifted by 8) of pid and put it in pf->dest_pid, you may think why he didn't send 2 bytes from the beginning, and the reason for that may be because he is getting it from a bus which sends only a byte per unit of time(cycle).

like image 4
Nasr Avatar answered Nov 15 '22 10:11

Nasr