This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: gcc 2.95.2 has problems with packing and alignment on AIX4.3(reformatted)


Well, I agree that the size of cd might not equal the size of dc, because as you say the compiler is free to 
pad and align things the way it wants.

But... the gcc manual says:

"The 'packed' attribute specifies that a variable or structure field should have the smallest possible
alignment-- one byte for a variable and one bit for a field, unless you specify a larger value with the 
'aligned' attribute."

That's pretty unambiguous isn't it ?  In this example it clearly isn't doing that.

Stepping back a little, the application here its to translate between an internal and external
representation of some data.  For years, through many compiler changes, we've used a packed structure
to make sure that data going into our database is formatted exactly as we intend, allowing cross-
architecture compatibility.  How better to do that than use a packed structure ?

If I was going to do this in perl instead of C I'd use the "pack" function.  See what I mean ?



Jeff Dickens
Software Tools Engineer
ERS Boxborough (978) 264-2832

>>> Mark Hahn <hahn@coffee.psychology.mcmaster.ca> 11/04 4:16 PM >>>
> One would think that the size of "dc" should equal that of "cd" and that 
> the size of "dc_packed" should equal that of "cd_packed".  It doesn't.

I'm not sure why you think this is a sensible conclusion: the compiler
is free (by the language standard) to put arbitrary padding in structs,
afaik.

> The real problem for us is that we believe the size of "dc_packed" 
> should be 9.  In fact our code was depending on it.  Is this a bad assumption, 
> and if so, exactly why ?

any such code is inherently unportable, which to most competent programmers
means "buggy".  still, you might try something like -mno-align-double;
the natural alignment of a struct isn't quite the same concept as whether
it has internal padding or not (packed).

regards, mark hahn.

===

since I can't make the "references" headers work with my mailer, here's the original message in full:

I have retested on the latest compiler and simplified my example program in the hope 
of getting some kind soul to help confirm or deny that there is a problem.

A good first step would be to try it on another platform.  It's a very short program, 
attached.

In the following example, "lc" is  a struct containing a long and a char, "cl" is a struct 
containing a char and a long, "cd" is a struct containing a char and a double, and 
"dc" is a struct containing a double and a char.

The example program just does a sizeof() on each of these 4 variables, as well as 
on an "__attributes__ ((packed))" version of the same.  Here's how it looks 
on one system we have running Gcc 2.8.1:

lc size 8
lc_packed size 5
cl size 8
cl_packed size 5
dc size 12
dc_packed size 9
cd size 12
cd_packed size 9

Now here's how it looks with Gcc 2.95.2 on AIX 4.3:

lc size 8
lc_packed size 5
cl size 8
cl_packed size 5
dc size 16
dc_packed size 16
cd size 12
cd_packed size 9

One would think that the size of "dc" should equal that of "cd" and that 
the size of "dc_packed" should equal that of "cd_packed".  It doesn't.

The real problem for us is that we believe the size of "dc_packed" 
should be 9.  In fact our code was depending on it.  Is this a bad assumption, 
and if so, exactly why ?

Here's the source code:

#include <stdio.h>

struct _cl
{
        char    c;
        long    l;
};


struct _lc
{
        long    l;
        char    c;
};


struct _cd
{
        char    c;
        double  d;
};


struct _dc
{
        double  d;
        char    c;
};


struct _cl_packed
{
        char    c_packed        __attribute__ ((packed));
        long    l_packed        __attribute__ ((packed));
};


struct _lc_packed
{
        long    l_packed        __attribute__ ((packed));
        char    c_packed        __attribute__ ((packed));
};


struct _cd_packed
{
        char    c_packed        __attribute__ ((packed));
        double  d_packed        __attribute__ ((packed));
};


struct _dc_packed
{
        double  d_packed        __attribute__ ((packed));
        char    c_packed        __attribute__ ((packed));
};


struct _lc lc;
struct _lc_packed lc_packed;

struct _cl cl;
struct _cl_packed cl_packed;

struct _dc dc;
struct _dc_packed dc_packed;

struct _cd cd;
struct _cd_packed cd_packed;

int main (int argc, char* argv[])
{

        printf ("lc size %d\n", sizeof(lc));
        printf ("lc_packed size %d\n", sizeof(lc_packed));

        printf ("cl size %d\n", sizeof(cl));
        printf ("cl_packed size %d\n", sizeof(cl_packed));

        printf ("dc size %d\n", sizeof(dc));
        printf ("dc_packed size %d\n", sizeof(dc_packed));

        printf ("cd size %d\n", sizeof(cd));
        printf ("cd_packed size %d\n", sizeof(cd_packed));

        exit (0);
}







Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]