Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

gcc byte packing of inherited class data

355 views
Skip to first unread message

Bruce Edge

unread,
Jun 22, 1999, 3:00:00 AM6/22/99
to
I can't get gcc to pack this data:

class a
{
char c;
};

class b
{
long l;
};

class c : public a, public b
{

};


Without going into why I need a misaligned long after a char,
I need the alignment for class c to be:

cc ll ll ll ll

not:

cc xx xx xx ll ll ll ll

which it insists on doing regardless of which attribute/packed
parameters I use.

TIA, Bruce.

--
Bruce Edge bedge@sat/_noXXXspam_/tel.com
Sattel Global Networks 818.709.6201 x122

Stefan Seefeld

unread,
Jun 22, 1999, 3:00:00 AM6/22/99
to
Bruce Edge wrote:
>
> I can't get gcc to pack this data:
>
> class a
> {
> char c;
> };
>
> class b
> {
> long l;
> };
>
> class c : public a, public b
> {
>
> };
>
> Without going into why I need a misaligned long after a char,
> I need the alignment for class c to be:
>
> cc ll ll ll ll
>
> not:
>
> cc xx xx xx ll ll ll ll

given your requested alignment, how would you expect a cast from
(c *) to (b *) to work ? It doesn't give a valid address.

Stefan
_______________________________________________________

Stefan Seefeld
Departement de Physique
Universite de Montreal
email: seef...@magellan.umontreal.ca

_______________________________________________________

...ich hab' noch einen Koffer in Berlin...

Bruce Edge

unread,
Jun 22, 1999, 3:00:00 AM6/22/99
to
Stefan Seefeld wrote:
>
> Bruce Edge wrote:
> >
> > I can't get gcc to pack this data:
> >
> > class a
> > {
> > char c;
> > };
> >
> > class b
> > {
> > long l;
> > };
> >
> > class c : public a, public b
> > {
> >
> > };
> >
> > Without going into why I need a misaligned long after a char,
> > I need the alignment for class c to be:
> >
> > cc ll ll ll ll
> >
> > not:
> >
> > cc xx xx xx ll ll ll ll
>
> given your requested alignment, how would you expect a cast from
> (c *) to (b *) to work ? It doesn't give a valid address.

I admit to being new to linux programming, but I'm not sure what you
mean by a valid address, are you referring to having a long on a
misaligned
boundry?
This works on QNX.

-Bruce.

Bruce Edge

unread,
Jun 22, 1999, 3:00:00 AM6/22/99
to
Bruce Edge wrote:
>
> I can't get gcc to pack this data:
>
> class a
> {
> char c;
> };
>
> class b
> {
> long l;
> };
>
> class c : public a, public b
> {
>
> };
>
> Without going into why I need a misaligned long after a char,
> I need the alignment for class c to be:
>
> cc ll ll ll ll
>
> not:
>
> cc xx xx xx ll ll ll ll
>
> which it insists on doing regardless of which attribute/packed
> parameters I use.
>

Just for the record, I'm constructing a packed to send out a serial
interface to a 16 bit controller, so the alignment is really important.

Adding packed attributes all over doesn't help either.

-Thanks, Bruce.

Don Waugaman

unread,
Jun 22, 1999, 3:00:00 AM6/22/99
to
In article <377005BF...@sattel.com>,
Bruce Edge <be...@sattel.com> wrote:
>Bruce Edge wrote:

[ class with a long inheriting from class with a char ]

>> Without going into why I need a misaligned long after a char,
>> I need the alignment for class c to be:

>> cc ll ll ll ll

>> not:

>> cc xx xx xx ll ll ll ll

>> which it insists on doing regardless of which attribute/packed
>> parameters I use.

>Just for the record, I'm constructing a packed to send out a serial
>interface to a 16 bit controller, so the alignment is really important.

>Adding packed attributes all over doesn't help either.

>-Thanks, Bruce.

You are probably out of luck. The C++ front end (which is interpreting
the pack attribute) is different from the C front end, and likely ignores
the attribute when applied to a class (at least as far as layout of
base/derived parts of objects).

Is performance that important for your application? Could you just build
the packed representation in a memory buffer using memcpy() of each
member and then send that through the serial port? Over the course of
time, that will end up being more maintainable.

If you want, you could try to ask this question on the egcs mailing list
(http://egcs.cygnus.com/ for details) but you should probably expect a
non-favorable reception and a suggestion like I've outlined above.
--
- Don Waugaman (d...@cs.arizona.edu) O- _|_ Will pun
Web Page: http://www.cs.arizona.edu/people/dpw/ | for food
In the Sonoran Desert, where we say: "It's a dry heat..." | <><
"Very funny, Scotty. Now beam down my clothes."

Tom Lane

unread,
Jun 23, 1999, 3:00:00 AM6/23/99
to
Bruce Edge <be...@sattel.com> writes:
> Without going into why I need a misaligned long after a char,

Real compilers (as opposed to Microsoft crap) won't let you do that,
period. Even if they are living on hardware that doesn't address-
fault on misaligned accesses, they won't let you commit that sin.

As a veteran of many portability problems, I can tell you that the
Only True Path is that a given struct declaration has a single
interpretation on a particular kind of hardware. *Anything* that
tries to alter that is spew of the devil, because it creates untold
potential for software incompatibilities of the worst kind (namely,
the kind that cause you to waste hours of work chasing "impossible"
bugs before you get that oh-no insight that it's not a code bug at
all, it's just that modules A and B have different ideas about the
layout of a struct that they supposedly share).

If you need a particular byte layout in memory, declare your structure
as a byte array and then write some routines to read/write it as
bytes. It may seem like a pain, but take my word for it: it beats
the alternative by a country mile.

regards, tom lane

Erwin S. Andreasen

unread,
Jun 23, 1999, 3:00:00 AM6/23/99
to
On Tue, 22 Jun 1999 18:27:42 +0000, Bruce Edge <be...@sattel.com> wrote:
>I can't get gcc to pack this data:
>
>class a
>{
> char c;
>};
>
>class b
>{
> long l;
>};
>
>class c : public a, public b
>{
>
>};

For a simple setup like this, this worked here:

class A { public: char a; };
class B { public:long b __attribute__((packed)); };
class C : public A, public B {
};

int main() {
C c;
c.a = 42;
c.b = 0;
};


After c.b = 0, I run gdb:

(gdb) p sizeof(c)
$5 = 5

Dumping the memory:

(gdb) x/16b &c
0xbffff8d0: 0x2a 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0xbffff8d8: 0x00 0x00 0x00 0x00 0xca 0x84 0x04 0x08

And to be absolutely sure:

(gdb) set variable c.b=0x01010101
(gdb) x/16b &c
0xbffff8d0: 0x2a 0x01 0x01 0x01 0x01 0x00 0x00 0x00
0xbffff8d8: 0x00 0x00 0x00 0x00 0xca 0x84 0x04 0x08


It seems packed to me.


# g++ -v
Reading specs from /usr/lib/gcc-lib/i486-linux/egcs-2.91.66/specs
gcc version egcs-2.91.66 19990314 (egcs-1.1.2 release)

SUSE 6.1, with glibc2.

--
==============================================================================
Erwin Andreasen Herlev, Denmark <e...@dde.dk> UNIX System Programmer
<URL:http://www.andreasen.org> <*> (not speaking for) DDE
==============================================================================

BOIRIE Gregor CNAM 98-99

unread,
Jun 26, 1999, 3:00:00 AM6/26/99
to
Bruce Edge (be...@sattel.com) wrote:
: Stefan Seefeld wrote:
: >
: > Bruce Edge wrote:
: > >
: > > I can't get gcc to pack this data:
: > >
: > > class a
: > > {
: > > char c;
: > > };
: > >
: > > class b
: > > {
: > > long l;
: > > };
: > >
: > > class c : public a, public b
: > > {
: > >
: > > };
: > >
: > > Without going into why I need a misaligned long after a char,
: > > I need the alignment for class c to be:

: > >
: > > cc ll ll ll ll
: > >
: > > not:
: > >
: > > cc xx xx xx ll ll ll ll
: >
: > given your requested alignment, how would you expect a cast from

Shankar Unni

unread,
Jul 3, 1999, 3:00:00 AM7/3/99
to
Bruce Edge wrote:

> I can't get gcc to pack this data:
> class a { char c; };
> class b { long l; };

> class c : public a, public b { };

> I need the alignment for class c to be:
> cc ll ll ll ll

No can do.

Most C++ compilers ignore packing attributes across base class
boundaries, because it's too painful to deal with possible unaligned
virtual table pointers, etc. And rather than try to distinguish between
classes that have virtual tables, and those that don't, many just apply
this rule in a blanket fashion.

Besides, I can conceive of situations in which a compiler cannot
determine whether a particular class is a member of a packed structure
or not.

Bottom line: if you want to play with packed structures, make sure that
the entire packed "structure" (in real life) is modeled by a single
packed struct in your code.

You can then wrap some other class around it to manipulate the contents
of this packed struct. Heck, you can do whatever sort of inheritance,
etc., that you want, provided that each subclass maintains its own
packed buffer separately, and you have some sort of composition and
unpacking methods at the top level to collect all the pieces of the
packed structure and assembles them for transmission, or vice versa.


--
Shankar Unni sha...@webnexus.com

0 new messages