Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does *(int*)(buffer) mean?

Tags:

c++

c

pointers

In a c++ code I am reading, found the following. Can anyone help me understand what does the following statements do?

char buffer[4096];
// some code
int size = *(int*)(buffer);
like image 780
shaikh Avatar asked May 11 '16 06:05

shaikh


2 Answers

char buffer[4096];//this is an array of 4096 characters
// some code

int size = *(int*)(buffer);

Will cast the(decayed) character pointer,which is buffer, to an integer pointer. It then dereferences it to get an integer value. The integer value you get from this will be composed of the first 4 character values of the buffer array assuming the size of int is 4 bytes in your machine, or in general will be composed of sizeof(int) characters.

In other words, the memory representation of the first sizeof(int) characters of the buffer array will be treated as though they represent a single integer value,since now it is pointed to by an integer pointer, and that will be stored in the size integer variable when that integer pointer is dereferenced.

That being said, as it has been stated repeatedly in the comments section, this code is unsafe. One thing that comes to mind is, some CPUs have a strict alignment requirements(see this answer), and in this case there is no guarantee that the address of the first element of the buffer array complies with the alignment requirement of an integer resulting in undefined operation in those CPUs.

See @Lundin answer for even more reason why this code is unsafe and may not give you the result you were looking for.

like image 176
Biruk Abebe Avatar answered Oct 13 '22 01:10

Biruk Abebe


TL;DR: this code is bad, forget about it and move on.


(buffer) This parenthesis means that the programmer was insecure of their own programming abilities.

Since buffer is an array of characters, using the identifier buffer on its own gives you a pointer to the first element: a char pointer.

(int*) This is a cast, converting the char pointer to an int pointer.

* takes the contents of that integer pointer and the result is stored in the integer size.

Please note that this code is completely unsafe. Many pointer conversions invoke poorly-defined behavior. There might be alignment issues. There might be pointer aliasing issues (Google "strict aliasing rule"). This particular code is also endianess-dependent, meaning that it requires that the contents of the character array has a given byte order.

Overall, it does not make any sense to use signed types like int or char (maybe signed) when doing things like this. In particular, the char type is very problematic since it has implementation-defined signedness and should be avoided. Use unsigned char or uint8_t instead.

Slightly less bad code would look something like this:

#include <stdint.h>

uint8_t buffer[4096];
// some code
uint32_t size = *(uint32_t*)buffer;
like image 30
Lundin Avatar answered Oct 12 '22 23:10

Lundin