Re: alignment/zero length arrays
- From: Barry Schwarz <schwarzb@xxxxxxxxx>
- Date: Fri, 25 Aug 2006 16:21:24 -0700
On 25 Aug 2006 11:28:07 -0700, "Bill Pursell" <bill.pursell@xxxxxxxxx>
wrote:
I have a program that does most of its work traversing
a bunch of lists. The lists contain a void *, and I spent
some time today replacing the void *'s with a copy
of the data at the end of the structure as a zero length
array. The performance improvement that resulted by
avoiding the need to dereference the ptr was substantial,
but it has left me with an uncertain feeling. In particular,
changing an assignment caused the output to change,
and I'm not happy about it. The change that I think
should not have any affect is:
We would have to see your real code to discuss this. For example, do
you reuse the struct?
struct foo *f;
f = (struct foo *)&list_element->zdata;
This sets pointer f to point to the data in your element.
becomes
struct foo f;
f = *(struct foo *)&list_element->zdata;
This copies the data from your element to the structure f.
This is better described with the full program below.
My question is: 1) Are the final 3 assignments in this program
reliable?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct foo {
int x,y,z;
};
struct list_el {
void *data;
/* other stuff that throws off alignment */
/* gnu extension...*/
char zdata[] __attribute__((aligned(8)));
The first part of this is a syntax error. (You could achieve the
intended result with [1].) The second part is non-standard. It also
begs the question how do you know 8 is the proper alignment.
};
extern void * xmalloc(size_t s);
int
main(void)
{
struct list_el *L;
struct foo orig = {0,1,2};
struct foo *copy_ptr;
struct foo copy;
L = xmalloc(sizeof *L + sizeof orig);
You don't provide xmalloc but I will assume it does the obvious.
L->data = &orig;
memcpy(&L->zdata, &orig, sizeof orig);
copy_ptr = (struct foo *)L->data;
The cast is superfluous. data is a void* which can be implicitly
converted to any other object pointer type.
In answer to your question, data contains the address of a struct foo.
copy_ptr is a pointer to struct foo. It is reliable to assign such an
address to such a pointer. The conversion to void* (three statements
prior) and from void* (here) are well defined.
copy_ptr = (struct foo *)&L->zdata;
This is "reliable" only if zdata is properly aligned to a struct foo.
copy = *(struct foo*)&L->zdata;
This also is "reliable" only if zdata is properly aligned.
return EXIT_SUCCESS;
}
Remove del for email
.
- Follow-Ups:
- Re: alignment/zero length arrays
- From: Bill Pursell
- Re: alignment/zero length arrays
- References:
- alignment/zero length arrays
- From: Bill Pursell
- alignment/zero length arrays
- Prev by Date: Re: Array for speed or...
- Next by Date: Re: Floating point load-store behaviour.
- Previous by thread: alignment/zero length arrays
- Next by thread: Re: alignment/zero length arrays
- Index(es):
Relevant Pages
|