This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Re: how do I tell gcc not to assume an alignment?
- From: Andrew Haley <aph at redhat dot com>
- To: "FlÃvio J. Saraiva" <flaviojs2005 at gmail dot com>
- Cc: gcc-help at gcc dot gnu dot org
- Date: Thu, 04 Jul 2013 09:41:06 +0100
- Subject: Re: how do I tell gcc not to assume an alignment?
- References: <CACTk=1BSHfieiaJdON7wnBDquznvDJuOvQ=OnC0Tj+YkOLjLHw at mail dot gmail dot com>
On 07/03/2013 05:26 PM, FlÃvio J. Saraiva wrote:
> In https://github.com/GNS3/dynamips-community/issues/9 I found that
> the reason for a crash was the compiler assuming that the pointer was
> 4-byte aligned in one of the O3 optimizations.
> Using gcc-4.4.7-3.el6.x86_64 in a Cent6.4-x86_64 box.
>
> I don't understand why it made that assumption, so I'd like to know
> how to tell the compiler not to assume an alignment.
There is attribute(aligned) and attribute(packed) but I don't think that
you need them for this.
GCC knows what the integer alignment for a machine is. It is
perfectly entitled to assume that a pointer to uint32_t really is
aligned, The only thing you are allowed to do in C is convert an int
pointer to a void* or a char* and then copy it back again. You can't
convert, say, a char* to an int* and us it as you're trying to do.
There is a saying: Do not lie to the compiler. It will bite you.
So, what's the right way to solve your problem?
Like this:
/* Byte-swap a memory block */
void mem_bswap32(void *ptr,size_t len)
{
m_uint32_t *p = ptr;
size_t count = len >> 2;
int i;
m_uint32_t x;
for(i=0;i<count;i++,p++)
{
memcpy(&x, p, sizeof x);
x = swap32(x);
memcpy(p, &x, sizeof x);
}
}
GCC will generate the best code it can for the memcpy(); this will be
the fastest kind of unaligned memory move that your processor
supports.
Andrew.