* Darwin gcc 3.3 sizeof of C++ structures with long long ints is strange
@ 2003-02-07 16:18 Kevin B. Hendricks
2003-03-19 12:30 ` Andrew Haley
0 siblings, 1 reply; 7+ messages in thread
From: Kevin B. Hendricks @ 2003-02-07 16:18 UTC (permalink / raw)
To: gcc
Hi,
I am exploring the use of gcc 3.3 (based on CVS from yesterday) to build
OpenOffice.org under MacOSX/Darwin (we have had troubles with Apple's gcc
3.1 that don't seem to happen under gcc 3.3)?
Unfortunately, the following structure alignment program shows the size of
structure C5 is 4 bytes larger than expected.
If you look at the code the key issue is that C5 uses a long long int type.
If I replace the long long int with a double (both are 8 bytes in size)
the expected size is achieved.
Will someone familar with C++ structure alignment and Darwin please take a
look at this testcase for me?
Is there something funny happening with long long ints here?
Thanks,
Kevin
My gcc 3.3 build is installed in /usr/local/
This is on MacOSX 10.2.3
setenv PATH /usr/local/bin:${PATH}
setenv DYLD_LIBRARY_PATH /usr/local/lib
[khendricksmac:~] kbhend% /usr/local/bin/g++ -DMAX4 -DADJUST_ALIGN -O2 -o
datatest datatest.cxx
[khendricksmac:~] kbhend% ./datatest
> sizeof(AlignSize_Impl) = 12; __alignof__ (AlignSize_Impl) = 4
> sizeof(M) = 8; __alignof__ (M) = 4
> sizeof(N) = 12; __alignof__ (N) = 4
> sizeof(N2) = 12; __alignof__ (N2) = 4
> sizeof(O) = 16; __alignof__ (O) = 4
> sizeof(D) = 8; __alignof__ (D) = 4
> sizeof(C1) = 2; __alignof__ (C1) = 2
> sizeof(C2) = 8; __alignof__ (C2) = 4
> sizeof(C3) = 20; __alignof__ (C3) = 4
> sizeof(C4) = 32; __alignof__ (C4) = 4
> sizeof(C5) = 48; __alignof__ (C5) = 8
### sizeof(C5) = 48 instead of expected 44!!!
> sizeof(C6) = 64; __alignof__ (C6) = 8
### sizeof(C6) = 64 instead of expected 52!!!
### OFFSET_OF(C6, c6) = 8 instead of expected 4!!!
### OFFSET_OF(C6, b6) = 56 instead of expected 48!!!
> sizeof(O2) = 24; __alignof__ (O2) = 4
> sizeof(Char3) = 3; __alignof__ (Char3) = 1
> sizeof(P) = 20; __alignof__ (P) = 4
Here is the testcase the issue seems to happen with long long types only
(see the C5 structure defintion)
cat datatest.cxx
#include <stdlib.h>
#include <stdio.h>
typedef struct _Any
{
void * pType;
void * pData;
void * pReserved;
} uno_Any;
typedef _Any Any;
// Patching the gcc 3 incompatible alignment change for linux
// This pragma macro is appended to every first member of a struct,
// iff the struct inherits from a base struct and the first member
// of this structure is not a double or [unsigned] long long.
#ifdef ADJUST_ALIGN
#define CPPU_GCC3_ALIGN( base_struct ) __attribute__ ((aligned (__alignof__
(base_struct))))
#else
#define CPPU_GCC3_ALIGN( base_struct )
#endif
typedef enum {
My_BYTE,
MY_CHAR,
MY_INT,
MY_LONG,
MY_LONGLONG,
MY_FLOAT,
MY_DOUBLE
} TypeClass;
#ifdef MAX4
#define MAX_ALIGNMENT_4
#endif
#define OFFSET_OF( s, m ) ((size_t)((char *)&((s *)16)->m -16))
#define BINTEST_VERIFY( c ) \
if (! (c)) { fprintf( stderr, "### binary compatibility test failed: "
#c " [line %d]!!!\n", __LINE__ ); /* abort();*/ }
#define BINTEST_VERIFYOFFSET( s, m, n ) \
if (OFFSET_OF(s, m) != n) { fprintf( stderr, "### OFFSET_OF(" #s ", "
#m ") = %d instead of expected %d!!!\n", OFFSET_OF(s, m), n ); /*
abort();*/ }
#define BINTEST_VERIFYSIZE( s, n ) \
fprintf( stderr, "> sizeof(" #s ") = %d; __alignof__ (" #s ") = %d\n",
sizeof(s), __alignof__ (s) ); \
if (sizeof(s) != n) { fprintf( stderr, "### sizeof(" #s ") = %d instead
of expected %d!!!\n", sizeof(s), n ); /* abort();*/ }
struct C1
{
signed short n1;
};
struct C2 : public C1
{
signed long n2 CPPU_GCC3_ALIGN( C1 );
};
struct C3 : public C2
{
double d3;
signed long n3;
};
struct C4 : public C3
{
signed long n4 CPPU_GCC3_ALIGN( C3 );
double d4;
};
struct C5 : public C4
{
signed long long n5;
unsigned char b5;
};
struct C6 : public C1
{
C5 c6 CPPU_GCC3_ALIGN( C1 );
unsigned char b6;
};
struct D
{
signed short d;
signed long e;
};
struct E
{
unsigned char a;
unsigned char b;
unsigned char c;
signed short d;
signed long e;
};
struct M
{
signed long n;
signed short o;
};
struct N : public M
{
signed short p CPPU_GCC3_ALIGN( M );
};
struct N2
{
M m;
signed short p;
};
struct O : public M
{
double p;
};
struct O2 : public O
{
double p2;
};
struct P : public N
{
double p2;
};
struct empty
{
};
struct second : public empty
{
int a;
};
struct AlignSize_Impl
{
signed short nInt16;
double dDouble;
};
struct Char1
{
char c1;
};
struct Char2 : public Char1
{
char c2 CPPU_GCC3_ALIGN( Char1 );
};
struct Char3 : public Char2
{
char c3 CPPU_GCC3_ALIGN( Char2 );
};
struct Char4
{
Char3 chars;
char c;
};
class BinaryCompatible_Impl
{
public:
BinaryCompatible_Impl();
};
BinaryCompatible_Impl::BinaryCompatible_Impl()
{
#ifdef MAX_ALIGNMENT_4
// max alignment is 4
BINTEST_VERIFYOFFSET( AlignSize_Impl, dDouble, 4 );
BINTEST_VERIFYSIZE( AlignSize_Impl, 12 );
#else
// max alignment is 8
BINTEST_VERIFYOFFSET( AlignSize_Impl, dDouble, 8 );
BINTEST_VERIFYSIZE( AlignSize_Impl, 16 );
#endif
// enum
BINTEST_VERIFY( sizeof( TypeClass ) == sizeof( signed long ) );
// any
BINTEST_VERIFY( sizeof(void *) >= sizeof(signed long) );
BINTEST_VERIFY( sizeof( Any ) == sizeof( _Any ) );
BINTEST_VERIFY( sizeof( Any ) == sizeof( void * ) * 3 );
BINTEST_VERIFYOFFSET( Any, pType, 0 );
BINTEST_VERIFYOFFSET( Any, pData, 4 );
BINTEST_VERIFYOFFSET( Any, pReserved, 8 );
// struct
BINTEST_VERIFYSIZE( M, 8 );
BINTEST_VERIFYOFFSET( M, o, 4 );
BINTEST_VERIFYSIZE( N, 12 );
BINTEST_VERIFYOFFSET( N, p, 8 );
BINTEST_VERIFYSIZE( N2, 12 );
BINTEST_VERIFYOFFSET( N2, p, 8 );
BINTEST_VERIFYSIZE( O, 16 );
BINTEST_VERIFYSIZE( D, 8 );
BINTEST_VERIFYOFFSET( D, e, 4 );
BINTEST_VERIFYOFFSET( E, d, 4 );
BINTEST_VERIFYOFFSET( E, e, 8 );
BINTEST_VERIFYSIZE( C1, 2 );
BINTEST_VERIFYSIZE( C2, 8 );
BINTEST_VERIFYOFFSET( C2, n2, 4 );
#ifdef MAX_ALIGNMENT_4
BINTEST_VERIFYSIZE( C3, 20 );
BINTEST_VERIFYOFFSET( C3, d3, 8 );
BINTEST_VERIFYOFFSET( C3, n3, 16 );
BINTEST_VERIFYSIZE( C4, 32 );
BINTEST_VERIFYOFFSET( C4, n4, 20 );
BINTEST_VERIFYOFFSET( C4, d4, 24 );
BINTEST_VERIFYSIZE( C5, 44 );
BINTEST_VERIFYOFFSET( C5, n5, 32 );
BINTEST_VERIFYOFFSET( C5, b5, 40 );
BINTEST_VERIFYSIZE( C6, 52 );
BINTEST_VERIFYOFFSET( C6, c6, 4 );
BINTEST_VERIFYOFFSET( C6, b6, 48 );
#else
BINTEST_VERIFYSIZE( C3, 24 );
BINTEST_VERIFYOFFSET( C3, d3, 8 );
BINTEST_VERIFYOFFSET( C3, n3, 16 );
BINTEST_VERIFYSIZE( C4, 40 );
BINTEST_VERIFYOFFSET( C4, n4, 24 );
BINTEST_VERIFYOFFSET( C4, d4, 32 );
BINTEST_VERIFYSIZE( C5, 56 );
BINTEST_VERIFYOFFSET( C5, n5, 40 );
BINTEST_VERIFYOFFSET( C5, b5, 48 );
BINTEST_VERIFYSIZE( C6, 72 );
BINTEST_VERIFYOFFSET( C6, c6, 8 );
BINTEST_VERIFYOFFSET( C6, b6, 64 );
#endif
BINTEST_VERIFYSIZE( O2, 24 );
BINTEST_VERIFYOFFSET( O2, p2, 16 );
BINTEST_VERIFYSIZE( Char3, 3 );
BINTEST_VERIFYOFFSET( Char4, c, 3 );
#ifdef MAX_ALIGNMENT_4
// max alignment is 4
BINTEST_VERIFYSIZE( P, 20 );
#else
// alignment of P is 8, because of P[] ...
BINTEST_VERIFYSIZE( P, 24 );
BINTEST_VERIFYSIZE( second, sizeof( int ) );
#endif
}
static BinaryCompatible_Impl aTest;
int main ()
{
exit(0);
}
^ permalink raw reply [flat|nested] 7+ messages in thread
* Darwin gcc 3.3 sizeof of C++ structures with long long ints is strange
2003-02-07 16:18 Darwin gcc 3.3 sizeof of C++ structures with long long ints is strange Kevin B. Hendricks
@ 2003-03-19 12:30 ` Andrew Haley
2003-03-19 14:22 ` Kevin B. Hendricks
2003-03-19 19:21 ` Kevin B. Hendricks
0 siblings, 2 replies; 7+ messages in thread
From: Andrew Haley @ 2003-03-19 12:30 UTC (permalink / raw)
To: Kevin B. Hendricks; +Cc: gcc
Kevin B. Hendricks writes:
>
> I am exploring the use of gcc 3.3 (based on CVS from yesterday) to build
> OpenOffice.org under MacOSX/Darwin (we have had troubles with Apple's gcc
> 3.1 that don't seem to happen under gcc 3.3)?
>
> Unfortunately, the following structure alignment program shows the size of
> structure C5 is 4 bytes larger than expected.
>
> If you look at the code the key issue is that C5 uses a long long int type.
> If I replace the long long int with a double (both are 8 bytes in size)
> the expected size is achieved.
>
> Will someone familar with C++ structure alignment and Darwin please take a
> look at this testcase for me?
>
> Is there something funny happening with long long ints here?
You may be aware that the way C++ structs are laid out in memory has
changed as a result of the multivendor C++ ABI.
It looks to me like sizeof(C5) is rounded up to a multiple of C5's
alignment. This is not very strange. If you don't want this to
happen, you can use __attribute__ ((packed)).
Andrew.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Darwin gcc 3.3 sizeof of C++ structures with long long ints is strange
2003-03-19 12:30 ` Andrew Haley
@ 2003-03-19 14:22 ` Kevin B. Hendricks
2003-03-20 0:14 ` David Edelsohn
2003-03-19 19:21 ` Kevin B. Hendricks
1 sibling, 1 reply; 7+ messages in thread
From: Kevin B. Hendricks @ 2003-03-19 14:22 UTC (permalink / raw)
To: Andrew Haley; +Cc: gcc
Hi,
This alignment issue does not exist in Apple's gcc 3.1 using
-malign-natural and does not exist in Apple's gcc 2.95 version either.
I talked to Geoff Keating about ti and he felt that the alignment
constraint of long long ints and the comment found in the gnu gcc 3.3 code
was wrong ands that long long ints should NOT have higher alignment
constraints than doubles.
So the problem is you are not aligning it to max 4 purely (long long ints
are the exception) nor are you using natural alignment (8 for double and
long long int).
So you ar enot abi compatible with anyone (apple's gcc versions included).
I have simply changed this in my own gcc 3.3 builds for Apple. Geoff was
actually looking for a volunteer to somehow rationalize the gnu gcc long
long int alignment for darwin with Apple's alignments.
Kevin
On March 19, 2003 05:20 am, Andrew Haley wrote:
> Kevin B. Hendricks writes:
> >
> > I am exploring the use of gcc 3.3 (based on CVS from yesterday) to
build
> > OpenOffice.org under MacOSX/Darwin (we have had troubles with Apple's
gcc
> > 3.1 that don't seem to happen under gcc 3.3)?
> >
> > Unfortunately, the following structure alignment program shows the
size of
> > structure C5 is 4 bytes larger than expected.
> >
> > If you look at the code the key issue is that C5 uses a long long int
type.
> > If I replace the long long int with a double (both are 8 bytes in
size)
> > the expected size is achieved.
> >
> > Will someone familar with C++ structure alignment and Darwin please
take a
> > look at this testcase for me?
> >
> > Is there something funny happening with long long ints here?
>
> You may be aware that the way C++ structs are laid out in memory has
> changed as a result of the multivendor C++ ABI.
>
> It looks to me like sizeof(C5) is rounded up to a multiple of C5's
> alignment. This is not very strange. If you don't want this to
> happen, you can use __attribute__ ((packed)).
>
> Andrew.
>
>
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Darwin gcc 3.3 sizeof of C++ structures with long long ints is strange
2003-03-19 12:30 ` Andrew Haley
2003-03-19 14:22 ` Kevin B. Hendricks
@ 2003-03-19 19:21 ` Kevin B. Hendricks
1 sibling, 0 replies; 7+ messages in thread
From: Kevin B. Hendricks @ 2003-03-19 19:21 UTC (permalink / raw)
To: Andrew Haley; +Cc: gcc
Hi Andrew,
This is what Geoff sent to me originally and what I modified to get back to
a layout more consistent with everyone else's. The ZI sent test code has
to pass for any platform porting OOo and does so for PPC Linux, S390
Linux, x86 Linux, Irix, NetBSD, FreeBSD, Apple gcc 2.95, Apple gcc 3.1
with -malign-natural, WIN, Solaris, etc.
Since gnu gcc 3.3 does not support -malign-natural, and does not follow the
max4 convention that Apple's gcc 2.95 did, the only solution was to fix
the "strange" (but as you point out technically correct) alignment just
used for long long ints to be more consistent with max 4. All of the
other platforms do not treat alignment of doubles and long long ints
differently in C++ structures.
The other solution would be to add -malign-natural support to gnu gcc 3.3.
for Darwin.
I hope this explains things a bit better.
Kevin
---snip---
Re: some Darwin C++ stucture size issues
Date: 15/02/03 08:29 pm
From: Geoff Keating <geoffk@geoffk.org>
To: kevin.hendricks@sympatico.ca
The problem you're seeing is most likely due to something in the
ADJUST_FIELD_ALIGN or maybe ROUND_TYPE_ALIGN macro in
config/rs6000/darwin.h in GCC. To save you a checkout, the Apple
compiler has:
/* APPLE LOCAL begin Macintosh alignment 2002-2-26 ff */
/* This now supports the Macintosh power, mac68k, and natural
alignment modes. It now has one more parameter than the standard
version of the ADJUST_FIELD_ALIGN macro.
The macro works as follows: We use the computed alignment of the
field if we are in the natural alignment mode or if the field is
a vector. Otherwise, if we are in the mac68k alignment mode, we
use the minimum of the computed alignment and 16 (pegging at
2-byte alignment). If we are in the power mode, we peg at 32
(word alignment) unless it is the first field of the struct, in
which case we use the computed alignment. */
#undef ADJUST_FIELD_ALIGN
#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED, FIRST_FIELD_P) \
(TARGET_ALIGN_NATURAL ? (COMPUTED) : \
(((COMPUTED) == RS6000_VECTOR_ALIGNMENT) \
? RS6000_VECTOR_ALIGNMENT \
: (MIN ((COMPUTED), \
(TARGET_ALIGN_MAC68K ? 16 \
: ((FIRST_FIELD_P) ? (COMPUTED) \
: 32))))))
I'm pretty sure that's not the same as FSF GCC, which has:
/* Darwin word-aligns FP doubles but doubleword-aligns 64-bit ints. */
#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
(TYPE_MODE (TREE_CODE (TREE_TYPE (FIELD)) == ARRAY_TYPE \
? get_inner_array_type (FIELD) \
: TREE_TYPE (FIELD)) == DFmode \
? MIN ((COMPUTED), 32) : (COMPUTED))
In particular, I think the comment is wrong.
--
- Geoffrey Keating <geoffk@geoffk.org>
On March 19, 2003 05:20 am, Andrew Haley wrote:
> Kevin B. Hendricks writes:
> >
> > I am exploring the use of gcc 3.3 (based on CVS from yesterday) to
build
> > OpenOffice.org under MacOSX/Darwin (we have had troubles with Apple's
gcc
> > 3.1 that don't seem to happen under gcc 3.3)?
> >
> > Unfortunately, the following structure alignment program shows the
size of
> > structure C5 is 4 bytes larger than expected.
> >
> > If you look at the code the key issue is that C5 uses a long long int
type.
> > If I replace the long long int with a double (both are 8 bytes in
size)
> > the expected size is achieved.
> >
> > Will someone familar with C++ structure alignment and Darwin please
take a
> > look at this testcase for me?
> >
> > Is there something funny happening with long long ints here?
>
> You may be aware that the way C++ structs are laid out in memory has
> changed as a result of the multivendor C++ ABI.
>
> It looks to me like sizeof(C5) is rounded up to a multiple of C5's
> alignment. This is not very strange. If you don't want this to
> happen, you can use __attribute__ ((packed)).
>
> Andrew.
>
>
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Darwin gcc 3.3 sizeof of C++ structures with long long ints is strange
2003-03-19 14:22 ` Kevin B. Hendricks
@ 2003-03-20 0:14 ` David Edelsohn
2003-03-20 5:28 ` Kevin B. Hendricks
0 siblings, 1 reply; 7+ messages in thread
From: David Edelsohn @ 2003-03-20 0:14 UTC (permalink / raw)
To: Kevin B. Hendricks; +Cc: Andrew Haley, gcc
The Apple PowerMac alignment was the same as AIX. Unless Apple
has changed their ABI, doubles are not naturally aligned, but long long
ints are.
David
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Darwin gcc 3.3 sizeof of C++ structures with long long ints is strange
2003-03-20 0:14 ` David Edelsohn
@ 2003-03-20 5:28 ` Kevin B. Hendricks
2003-03-20 8:04 ` David Edelsohn
0 siblings, 1 reply; 7+ messages in thread
From: Kevin B. Hendricks @ 2003-03-20 5:28 UTC (permalink / raw)
To: David Edelsohn; +Cc: Andrew Haley, gcc
Hi,
That's interesting to know. That means any AIX port of OOo would run into
the same difficulties. Does the AIX gcc version support anything like
-malign-natural does for Apple's gcc 3.1 (byte aligned to 1, short aligned
to 2, int aligned to 4, double and long long int aligned to 8)?
Any particular reason for treating long long ints differently from doubles?
Thanks,
Kevin
On March 19, 2003 06:52 pm, David Edelsohn wrote:
> The Apple PowerMac alignment was the same as AIX. Unless Apple
> has changed their ABI, doubles are not naturally aligned, but long long
> ints are.
>
> David
>
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Darwin gcc 3.3 sizeof of C++ structures with long long ints is strange
2003-03-20 5:28 ` Kevin B. Hendricks
@ 2003-03-20 8:04 ` David Edelsohn
0 siblings, 0 replies; 7+ messages in thread
From: David Edelsohn @ 2003-03-20 8:04 UTC (permalink / raw)
To: Kevin B. Hendricks; +Cc: Andrew Haley, gcc
>>>>> Kevin B Hendricks writes:
Kevin> That's interesting to know. That means any AIX port of OOo would run into
Kevin> the same difficulties. Does the AIX gcc version support anything like
Kevin> -malign-natural does for Apple's gcc 3.1 (byte aligned to 1, short aligned
Kevin> to 2, int aligned to 4, double and long long int aligned to 8)?
Kevin> Any particular reason for treating long long ints differently from doubles?
The AIX port of GCC does not have the equivalent of
-malign-natural. IBM's Visual Age compiler may have a similar option
which could be provided for AIX GCC as well.
At the time the AIX ABI was being developed (late 1980's), 64-bit
"long long int" extension did not exist and double was the only 64-bit
quantity. The RIOS implementation of the POWER architecture could handle
word-aligned doubles, so the ABI architects decided why make "double" the
odd-ball with stricter alignment than all other types. By the time "long
long int" was introduced, they decided to be more forward-thinking, but
they could not break the ABI and correct "double" alignment.
David
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2003-03-20 5:44 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-02-07 16:18 Darwin gcc 3.3 sizeof of C++ structures with long long ints is strange Kevin B. Hendricks
2003-03-19 12:30 ` Andrew Haley
2003-03-19 14:22 ` Kevin B. Hendricks
2003-03-20 0:14 ` David Edelsohn
2003-03-20 5:28 ` Kevin B. Hendricks
2003-03-20 8:04 ` David Edelsohn
2003-03-19 19:21 ` Kevin B. Hendricks
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).