The corresponding version of the old "structural hacking" (?)

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; /* other members follow */ } Header; typedef struct Value { int type; union { int intval; double fltval; } v; } Value; /* round up to nearest multiple of sizeof(Value) so that a Header struct fits in */ size_t n_hdr = (sizeof(Header) + sizeof(Value) - 1) / sizeof(Value); size_t n_arr = 42; /* arbitrary array size here */ 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?

+13
c c89
Aug 19 '13 at 9:45
source share
1 answer

The "obvious" (well ... not entirely obvious, but this is what comes to my mind :-)), to make it break, use the vectorization compiler, which somehow decides to load it normally, say 64 Header to the vector register from the 42-rounded up-64 + region in hdr , which comes from malloc , which always allocates enough for vectorization. Saving the vector register back to memory may overwrite one of Value s.

I think this vector compiler can point to a standard (well, if the compiler has fingers ...) and require compliance.

In practice, however, I expect this code to work. If you run into a vectorized compiler, add even more space (round up with a machine-specific macro that can insert a minimum) and charge .:-)

+5
Aug 19 '13 at 15:21
source share



All Articles