I believe that I have found a way to achieve something like the famous “hack structure” in the portable C89. I am curious if this really strictly matches the C89.
Main idea: I allocate a large enough memory to contain the initial structure and elements of the array. The exact size is (K + N) * sizeof(array_base_type) , where K is chosen so that K * sizeof(array_base_type) >= sizeof(the_struct) and N number of elements in the array.
First, I will play out the pointer that malloc() returned to store the_struct , then I use pointer arithmetic to get a pointer to the beginning of the array following the structure.
One line of code costs more than a thousand words, so here is a minimal implementation:
typedef struct Header { size_t length; } Header; typedef struct Value { int type; union { int intval; double fltval; } v; } Value; size_t n_hdr = (sizeof(Header) + sizeof(Value) - 1) / sizeof(Value); size_t n_arr = 42; void *frame = malloc((n_hdr + n_arr) * sizeof(Value)); if (!frame) return NULL; Header *hdr = frame; Value *stack_bottom = (Value *)frame + n_hdr;
My main problem is that the last two assignments (using frame as a pointer to a header and a pointer to a value) may violate the strict anti-aliasing rule. However, I am not redefining hdr as a pointer to Value - it is just pointer arithmetic that is executed on frame to access the first element of the array of values, so I cannot effectively access the same object using pointers of different types.
So, is this approach better than the classic hacker (which is officially considered UB), or is he also UB?
c c89
user529758 Aug 19 '13 at 9:45 a.m. 2013-08-19 09:45
source share