-10

I have seen the the last sentence at some source code.please explain me what is this.

unsigned int dataPos;
unsigned char header[54];
dataPos    = *(int*)&(header[0x0A]);
  • 1
    It's only an `unsigned int`. It even says so in the first line. You'll have to be more explicit in what you don't understand. – Jongware Sep 17 '15 at 15:49
  • 2
    Do you know what the address-of operator `&` does? Do you know what C-style casting like `(int *)` does? Do you know what the dereference operator `*` does? And you *do* know what array-indexing does? Then you basically know everything there is to know, and how to decipher that expression. – Some programmer dude Sep 17 '15 at 15:51
  • This is obfuscated C++, that's what this is. And undefined behavior, if that array isn't initialized. – Beta Sep 17 '15 at 15:54
  • @Beta afair it's might also be undefined behavior because of alignment issues. This essentially only works reliably if `(header + 0x0a)` was an `int *) in the first place. You'll still see stuff like this in badly written network protocol stacks, e.g. this might be try to extract the packet length from the header. – dhke Sep 17 '15 at 15:59
  • 1
    @dhke: If that's true it's news to me; can you point me to a reference (no pun intended)? – Beta Sep 17 '15 at 16:01

4 Answers4

3
unsigned int dataPos; // dataPos is defined as unsigned integer
unsigned char header[54]; // header is an array of unsigned chars

The last line is a bit messy, but here is how you can decompose it:

unsigned char *tmp1 = &header[0x0A]; // take the pointer to the tenth element
int *tmp2 = (int *)tmp1;             // convert it to a pointer to int
dataPos = *tmp2;                     // copy the integer tmp2 points to to dataPos

Actually, this expression is not 100% safe, because the original array header is defined as array of unsigned chars, later the bytes starting from position 10 are accessed as an integer. On most platfroms integers are aligned so that the address is divisible by 4, while array of chars can start at any address. It means that tenth element is probably not aligned. This can cause a runtime error on some platforms.

2

This is something that one should do very carefully.

It takes the address of the 11th (0x0A) element of the header array (&(header[0x0A]) is equivalent to (header + 0x0A)) and converts the char *const pointer to an int * pointer and then accesses the (potential) integer stored at that location.

It then converts that int into an unsigned int (which is fine).

So basically: "There's an int inside that char array at position 10 (counting from 0). Go there and pick it up.

As far is I know this is only defined behavior if that address was used for storing an int previously, otherwise you might get into a load of undefined behavior issues including but not limited to alignment problems.

dhke
  • 15,008
  • 2
  • 39
  • 56
  • I think it's defined if that address -- and enough of the following ones to make an `int` -- were used to store *something*. – Beta Sep 17 '15 at 15:56
  • 1
    I remember more or less exactly [that discussion](https://stackoverflow.com/questions/13881487/should-i-worry-about-the-alignment-during-pointer-casting) in another SO question, recently (not necessarily the linked one). It was at least suggested that the standard allows implementations to require only aligned integer access and hence to simply croak if trying non-aligned access. – dhke Sep 17 '15 at 16:03
1

Please, could you specify which part/operator of the line you don't understand! any way the sentence is composed by the following elements:

  1. *: de-reference operator
  2. (int*): cast to int
  3. &: address-of operator
  4. header[0x0A]: array value stored at position 10

So basically it's "reading" the integer formed by bytes stored in the position 10,11,12 and 13 of the header array and storing it in the variable dataPos.

rkachach
  • 16,517
  • 6
  • 42
  • 66
0

Maybe my comments would help:

unsigned int dataPos; // integer value
unsigned char header[54]; // character array (string)
dataPos    = *(int*)&(header[0x0A]);

// first 0x0a = 0xA = 10
// so header[0x0A] means get 10th element of array
// & in front of something means get address of
// so get address of (pointer to char) 10 element.
// now *(int *) is tricky (int *) would convert address you of 
//       header[10] and convert it to int pointer.
//
// finaly * in front of (int *) would say get the value stored in adress pointed to