Let us not discuss the badness of the following code, it's not mine, and I fully agree with you in advance that it's not pretty, rather C-ish and potentially very dangerous:
void * buf = std::malloc(24 + sizeof(int[3]));
char * name = reinterpret_cast<char *>(buf);
std::strcpy(name, "some name");
int * values = reinterpret_cast<int *>(name + 24);
values[0] = 0; values[1] = 13; values[2] = 42;
Its intent is quite clear; it's a "byte block" storing two arrays of different
types. To access elements not in front of the block, it interprets the block as
char *
and increments the pointer by sizeof(type[len])
.
My question is however, is it legal C++(11), as in "is it guaranteed that it will work on every standard conforming compiler"? My intuition says it's not, however g++ and clang seem to be fine with it.
I would appreciate a standard quote on this one; unfortunately I was not able to find a related passage myself.
This is perfectly valid C++ code (not nice though, as you noted yourself). As long as the string is not longer than 23 characters, it is not even in conflict with the strict aliasing rules, because you never access the same byte in memory through differently typed pointers. However, if the string exceeds the fixed limit, you have undefined behaviour like any other out of bounds bug.
Still, I'd recommend to use a structure, at the very least:
typedef struct whatever {
char name[24];
int [3];
} whatever;
whatever* myData = new myData;
std::strcpy(myData->name, "some name");
myData->values[0] = 0; myData->values[1] = 13; myData->values[2] = 42;
This is 100% equivalent to the code you gave, except for a bit more overhead in the new
operator as opposed to directly calling malloc()
. If you are worried about performance, you can still do whatever* myData = (whatever*)std::malloc(sizeof(*myData));
instead of using new.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With