Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 12 Nov 2006 18:57:23 +0300
From:      Ruslan Ermilov <ru@freebsd.org>
To:        Giorgos Keramidas <keramida@freebsd.org>
Cc:        arm@freebsd.org, current@freebsd.org
Subject:   Re: [head tinderbox] failure on arm/arm
Message-ID:  <20061112155723.GB50349@rambler-co.ru>
In-Reply-To: <20061112151150.GA2988@kobe.laptop>
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>

next in thread | previous in thread | raw e-mail | index | archive | help

--H+4ONPRPur6+Ovig
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Sun, Nov 12, 2006 at 04:11:51PM +0100, Giorgos Keramidas wrote:
> On 2006-11-12 17:51, Ruslan Ermilov <ru@FreeBSD.org> wrote:
> > On Sun, Nov 12, 2006 at 03:42:30PM +0100, Giorgos Keramidas wrote:
> > > 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
> > > > %%%
> > > >
> > > > (None of other supported architecutes see the issue here.)
> > >=20
> > > You can't cast any random (char *) pointer to a pointer of a type whi=
ch
> > > is (potentially) larger than 1 byte.  It's the same sort of warning y=
ou
> > > will get if you try to:
> > >=20
> > >     char ch[] =3D "\x00\x00\x00\x00";
> > >     char *p =3D &(ch[0]);
> > >     unsigned long *lptr =3D (unsigned long *)p;
> > >=20
> > > You cannot guarantee that `ch' is stored in an address that is proper=
ly
> > > aligned for (unsigned long), and this is what GCC warns about here.
> >=20
> > No, your example I perfectly understand but it is completely different.
> > Note that the first (and only) member in my structure is "char", so it
> > doesn't need to be more than sizeof(char) aligned.
>=20
> 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.
>=20
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>
: =20
: -struct foo;
: +struct foo {
: +       char x;
: +};
: =20
:  struct foo *
:  bubu(char *s)
:  {
: =20
:         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

> > > On 2006-11-12 15:27, Stefan Farfeleder <stefan@fafoe.narf.at> wrote:
> > > > What is sizeof(struct foo)?  If it's > 1 it makes sense.
> > >=20
> > > Exactly :)
> >=20
> > Still doesn't make much sense to me.  If all structure members are chars
> > (like is the case with "struct ar_hdr" from <ar.h> which GCC complains
> > about, and in my example, the required alignment shouldn't be more than
> > sizeof(char).  What am I missing?
>=20
> You are missing that inside bubu() the compiler 'believes' that:
>=20
>     * The `s' pointer is (char *)-aligned.
>=20
>     * The sizeof(struct foo) is >1.
>=20
>     * 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 *).
>=20
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.  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) >=3D sizeof(x).  Fortunately,
not all that bad, and compiling the following snippet on sparc64:

: #include <stdio.h>
:=20
: struct foo1 {
:         char foo[4];
: };
:=20
: struct foo2 {
:         int foo;
: };
:=20
: int
: main(char *s)
: {
:         struct foo1 *foo1 =3D (struct foo1 *)s;
:         struct foo2 *foo2 =3D (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!).


Cheers,
--=20
Ruslan Ermilov
ru@FreeBSD.org
FreeBSD committer

--H+4ONPRPur6+Ovig
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (FreeBSD)

iD8DBQFFV0RjqRfpzJluFF4RAlAOAKCXFEwLbtRFOFq2kvM8B5/Xgu1VJACdEFva
Cdzbot64aK6bvxSbXCKw3iI=
=/D0P
-----END PGP SIGNATURE-----

--H+4ONPRPur6+Ovig--



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