Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 12 Nov 2006 19:00:32 +0100
From:      Giorgos Keramidas <keramida@freebsd.org>
To:        Ruslan Ermilov <ru@freebsd.org>
Cc:        arm@freebsd.org, current@freebsd.org
Subject:   Re: [head tinderbox] failure on arm/arm
Message-ID:  <20061112180031.GC4237@kobe.laptop>
In-Reply-To: <20061112155723.GB50349@rambler-co.ru>
References:  <20061112133929.9194773068@freebsd-current.sentex.ca> <20061112140010.GA47660@rambler-co.ru> <20061112142710.GE91556@wombat.fafoe.narf.at> <20061112133929.9194773068@freebsd-current.sentex.ca> <20061112140010.GA47660@rambler-co.ru> <20061112144230.GC2331@kobe.laptop> <20061112145151.GC49703@rambler-co.ru> <20061112151150.GA2988@kobe.laptop> <20061112155723.GB50349@rambler-co.ru>

next in thread | previous in thread | raw e-mail | index | archive | help
On 2006-11-12 18:57, Ruslan Ermilov <ru@freebsd.org> wrote:
> On Sun, Nov 12, 2006 at 04:11:51PM +0100, Giorgos Keramidas wrote:
> > Ah, but the tricky part is that inside bubu() there is no knowledge that
> > `s' may be properly aligned for a (struct foo *) pointer.  All the
> > compiler knows is that it is a (char *), possibly misaligned for any
> > pointer whose object has a size > 1.
>
> I don't think you're right.  If I don't declare a structure so that the
> compiler REALLY doesn't know the alignment requirement, it doesn't even
> complain (this is on ARM):
>
> : $ diff -u20 a.c b.c
> : --- a.c Sun Nov 12 18:19:34 2006
> : +++ b.c Sun Nov 12 18:19:22 2006
> : @@ -1,10 +1,12 @@
> :  #include <stdio.h>
> :
> : -struct foo;
> : +struct foo {
> : +       char x;
> : +};
> :
> :  struct foo *
> :  bubu(char *s)
> :  {
> :
> :         return (struct foo *)s;
> :  }
> : $ cc -c -Wcast-align a.c
> : $ cc -c -Wcast-align b.c
> : b.c: In function `bubu':
> : b.c:11: warning: cast increases required alignment of target type

The type of (struct foo) in a.c is an "incomplete type" (a type for
which the compiler has no size information yet, c.f. ISO/IEC 9899:1999
§6.2.5 (1)).  This is probably it doesn't complain about the same
problem in `a.c'.

What I *don't* know and I can't explain is why sizeof(struct foo) in
`b.c' is larger than 1 byte.

>>On 2006-11-12 17:00, Ruslan Ermilov <ru@freebsd.org> wrote:
>>> %%%
>>> $ cat a.c
>>> struct foo {
>>>   char x;
>>> };
>>>
>>> struct foo *
>>> bubu(char *s)
>>> {
>>>
>>>   return (struct foo *)s;
>>> }
>>> $ cc -c -Wcast-align a.c
>>> a.c: In function `bubu':
>>> a.c:9: warning: cast increases required alignment of target type
>>> %%%
>>
>> You are missing that inside bubu() the compiler 'believes' that:
>>
>>     * The `s' pointer is (char *)-aligned.
>>
>>     * The sizeof(struct foo) is >1.
>>
>>     * You are trying to assign `s' (with it's possibly misaligned
>>       value) to the `return value' place, whose type is (at
>>       least, as far as the compiler knows) is (struct foo *).
>
> I will assume that under a "misaligned value" you mean a data that the
> `s' pointer points to.  Assigning a pointer to pointer isn't a problem
> per se, there are no alignment issues here; dereferencing an assigned
> pointer later might be a problem if it points to an object with more
> strict alignment requirement.

Right.  But the compiler can't really tell if you *are* dereferencing
the return value of bubu() somewhere else, just by looking at the
definition of bubu()'s body.  So it warns you about a potentially
problematic cast.

> This is all clear and fine, I understand how all this works.  :-)
> What I don't seem to understand (and you didn't tell me) is why the
> alignment requirement for "struct foo" is >1.  From the above it looks
> like you're thinking that __alignof__(x) >= sizeof(x).  Fortunately,
> not all that bad, and compiling the following snippet on sparc64:
>
> : #include <stdio.h>
> :
> : struct foo1 {
> :         char foo[4];
> : };
> :
> : struct foo2 {
> :         int foo;
> : };
> :
> : int
> : main(char *s)
> : {
> :         struct foo1 *foo1 = (struct foo1 *)s;
> :         struct foo2 *foo2 = (struct foo2 *)s;
> :         printf("%jd %jd\n", __alignof__(*foo1), __alignof__(*foo2));
> : }
>
> Only complains about the second assignment:
>
> : a.c: In function `main':
> : a.c:15: warning: cast increases required alignment of target type
>
> Running it outputs: "1 4".  Similarly for "struct ar_hdr", whose all
> members are character arrays, also has the alignment requirement of
> 1 byte (verified on sparc64).
>
> So your sizeof() argument, well...  I don't understand it and it
> doesn't make things clearer at least to me.  I still believe this
> is bug in GCC that the alignment requirement is so high for a
> "struct foo { char x; }" (there's no real reason for this!).

I tried accessing panther.freebsd.org to test this on sparc64 earlier,
but it doesn't seem to work from here.  I can't really explain why on
ARM the alignment requirements seem odd, though.




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20061112180031.GC4237>