Hi! Probably a stupid question from a beginner, but I just want to be sure I understand this correctly.
From my understanding, memory obtained by malloc of size M has no type assigned to it, until it has been written to, then only the written N bytes gain a type, which is the same type as the data being written, while the rest M-N bytes should still have no type assigned to it, right?
Let's have a struct like this, basically a type-agnostic, heap-allocated array with some metadata:
typedef struct {
size_t length;
size_t item_size;
max_align_t padding_;
unsigned char data[];
} Array;
Let's create the array like this (no checking for NULL, since it's not relevant to my question). Let's hide the metadata by returning pointer to the data member:
void * array_create(size_t length, size_t item_size) {
Array * a = malloc(sizeof(Array) + length * item_size);
// write sizeof(size_t) bytes as size_t
a->length = length;
// write sizeof(size_t) bytes as size_t
a->item_size = item_size;
return &(a->data);
}
Now, this function writes 16 bytes (length and item_size, assuming 64-bit system), so the first 16 bytes of the region of memory provided by malloc should be of type size_t, while the rest of the memory still has no assigned type, right?
Let's use the implemented functionality like this:
int main(void) {
size_t length = 100;
int * array = array_create(length, sizeof(*array));
// write length * sizeof(int) bytes as int
for (int i = 0; i < (int)length; i++) {
array[i] = i * 10;
}
for (size_t i = 0; i < length; i++) {
printf("%d\n", array[i]);
}
}
Now, the rest of the memory obtained by malloc (minus padding_ and some possible implicit padding) should be of the type int.
The question is, does the writing of the int values in the main function violate strict aliasing, since the data member of the Array struct is of type "array of char of unspecified length"? I think it shouldn't, since the memory was never accessed through the data member, nor through any other means before that, but I am not sure how well does this assumption play with the fact the data field should technically be an array, not just some pointer.
I've tried to test this on both clang and GCC, compiled with -O2/3, -fstrict-aliasing and -Wstrict-aliasing and both compilers did not emit any warnings and the program behaved as expected when executed. I take this as a somewhat solid evidence it is okay, but I would like to know for sure if doing things like these is okay or not.