0

It seems to me that the buffer is being modified. Does it put 6 integers and then 5 floats into the buffer? It's also strange that they set size to 44 instead of 1024*sizeof(char). Perhaps the whole buffer is passed to write() but write() writes only the first 44 bytes to the client.

Could you please explain line by line? I have no experience with c++.

char buf[1024];
int* pInt = reinterpret_cast<int*>(buf);
*pInt = 5;
*(pInt+1) = 2;
*(pInt+2) = 3;  
*(pInt+3) = 4;
*(pInt+4) = 5;
*(pInt+5) = 6;

float* pFloat = reinterpret_cast<float*>(pInt+6);
*pFloat = 111;
*(pFloat+1) = 222;
*(pFloat+2) = 333;
*(pFloat+3) = 444;
*(pFloat+4) = 555;

int n;
int size = (1+2*5)*4;
n = write(buf, size);

1 Answers1

6

Does it put 6 integers and then 5 floats into the buffer?

Yes.

It's also strange that they set size to 11 instead of 1024*sizeof(char)

They don't want to write the entire buffer. Thy want to write just the ints and floats that were written to the buffer.

FWIW, that is poorly written code. It assumes that sizeof(int) and sizeof(float) are both equal to 4. A more portable method would use:

int size = 6*sizeof(int) + 5*sizeof(float);

Caution

Even though the posted code might work under some, perhaps most, circumstances, use of

int* pInt = reinterpret_cast<int*>(buf);
*pInt = 5;

is cause for undefined behavior by the standard. It violates the strict aliasing rule. There wasn't an int to begin with at that location.

Had you used:

int array[5] = {};
char* cp = reinterpret_cast<char*>(array);

// ...

int* iptr = reinterpret_cast<int*>(cp);
*iptr = 10;

there would be no problem since cp points to a place where an int was there to begin with.

For your use case, it will be better to use:

char buf[1024];
int intArray[] = {5, 2, 3, 4, 5, 6};
std::memcpy(buff, intArray, sizeof(intArray));

float floatArray = {111, 222, 333, 444, 555};
std::memcpy(buff+sizeof(intArray), floatArray, sizeof(floatArray));

int n;
int size = sizeof(intArray) + sizeof(floatArray);
n = write(buf, size);

Further reading:

  1. reinterpret_cast creating a trivially default-constructible object
  2. Unions and type-punning
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • No, `reinterpret_cast` does not create objects. https://stackoverflow.com/q/40873520/3002139 – Baum mit Augen Feb 08 '18 at 23:22
  • You may want to note this [violates stict aliasing](https://stackoverflow.com/q/98650/1708801) and the correct way to type pun in C++ is [via memcpy](https://stackoverflow.com/a/31080901/1708801) – Shafik Yaghmour Feb 08 '18 at 23:22
  • @BaummitAugen where does the answer state that `reinterpret_cast` creates objects or assumes so? – Fureeish Feb 08 '18 at 23:31
  • @Fureeish *"Does it put 6 integers and then 5 floats into the buffer? Yes."* <- There. There are no integer of float objects at the relevant places in this code. – Baum mit Augen Feb 08 '18 at 23:33
  • @ShafikYaghmour: Strict aliasing doesn't apply to `char*` pointers, though. It is an explicit exception to the rule. And a `char[]` array decays into a `char*` pointer. – Remy Lebeau Feb 08 '18 at 23:33
  • @BaummitAugen so you're saying that `int* pInt = reinterpret_cast(buf); *pInt = 5;` does not correctly place the binary sequence that represents an integer `5` in the very beginning of memory occupied by `buf`? – Fureeish Feb 08 '18 at 23:36
  • @RemyLebeau this is absolutely wrong, you are allowed to alias via a `char` but this code aliases via an `int` and `float` both are very much strict aliasing violations. – Shafik Yaghmour Feb 08 '18 at 23:37
  • @Fureeish It's not about the binary sequence either. There just is no `int` object that can be assigned to to begin with. Read the link. – Baum mit Augen Feb 08 '18 at 23:38
  • Actually, the problem is not strict aliasing. `char*` may alias anything. – Baum mit Augen Feb 08 '18 at 23:41
  • @BaummitAugen, sorta. If I am not mistaken, "Any pointer type -> `char*` -> same pointer type -> deference pointer" is ok. "`char*` -> another pointer type -> dereference pointer" violates the strict aliasing rule. – R Sahu Feb 08 '18 at 23:44
  • @RSahu Hm, I think saying there is no `int` or `float` to assign to to begin with would be a more precise way of stating the core problem, wouldn't it? – Baum mit Augen Feb 08 '18 at 23:46