Consider the following homogeneous struct:
struct myStruct {
void* a;
char* b;
int* c;
};
It is homogeneous, I believe, because all of the datatypes are pointers.
Given this struct would the following code be valid and portable across C99?
int main()
{
void* x = NULL;
char* y = "hello";
int* z = malloc(sizeof(int) * 10);
z[2] = 10;
void** myArray = malloc(sizeof(void*) * 3);
myArray[0] = x;
myArray[1] = y;
myArray[2] = z;
struct myStruct* s = (struct myStruct*)myArray;
printf("%p %s %d\n", s->a, s->b, s->c[2]);
return 0;
}
I understand that structs will often add padding between components in order to keep the size of the struct consistent, however, because the types of the pointers are all the same, is it a safe assumption that no padding will be added? I'm not necessarily asking if there is a 100% guarantee (I understand this is completely implementation specific, and that a compiler could add padding for obscure reasons), more I am asking for what reasons padding might be added to a homogeneous struct, if any reasons at all.
The code violates aliasing rules. The types void* and struct myStruct are not compatible, and no exceptions apply in this case. The dereference of the struct pointer in the printf statement causes undefined behavior:
printf("%p %s %d\n", s->a, s->b, s->c[2]);
This is true even if the structure has the same size as three void pointers, has no padding, and has the same alignment requirements.
No it's not portable. The size of pointers may actually differ which means there may be padding in your structure.
On most modern platforms this won't be a problem, but there's nothing in the standard that says all pointers have to be equal in size. Only that pointers are implicitly convertible from and to void *
.
A good example of a platform where pointer sizes differs is DOS (which is still actively used, for example on embedded systems) and other 16-bit segmented systems.
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