Alignment issues with Sun C Compiler

Alignment issues with Sun C Compiler

Post by Jogche » Thu, 04 Mar 2004 04:52:09



Hello,

I have some serious problems with the pack() pragma with sun cc:

I'd like to have the members of a few structures packed. That is without
any additional (compiler-dependent) padding between the members so that
it can be used for binary communication with other systems. To
accomplish this i surrounded the declaration of my structure with the
pack pragma:

int main() {
#pragma pack(1)
     struct { short x; long y; char z; } blah;
#pragma pack()
     blah.x = blah.y = blah.z = 1;

     return 0;

Quote:}

This indeed seems to pack the structure, however accessing the members
generates a misalignment exception (SIGBUS):

(from dbx)

signal BUS (invalid address alignment) in main at line 6 in file "k.c"
     6      blah.x = blah.y = blah.z = 1;

Ok, i would have expected the compiler to schedule (synthesized,
consisting out of 2 loads/stores + shift + or to load/store from an
abitrary address) unaligned load/store instructions to access the fields
of this packed structure.. Well, i thought, there would be an easy
solution: By providing a different structure layout where the members
requiring the highest alignment are placed first and in order this
problem could be solved:

int main() {
#pragma pack(1)
     struct { long y; short x; char z; } blah;
#pragma pack()
     blah.x = blah.y = blah.z = 1;

     return 0;

Quote:}

Sadly this does not solve the problem, i get again a SIGBUS, some closer
inspection with dbx shows that the starting address of 'blah' is
misaligned itself.. I would have expected the compiler to align the
whole structure at least on the natural alignment of the first member
which would in this case be sizeof(long):

signal BUS (invalid address alignment) in main at line 5 in file "k.c"
     5       blah.x = blah.y = blah.z = 1;
(dbx) print &blah
&blah = 0xffbff37d

Obviously as you can see the address of blah is not aligned on a 4-byte
(sizeof(long) == 4 on sparcv8) alignment and this is causing the
alignment exception.

My third attempt is to explicitly tell the compiler what alignment i want:

int main() {
#pragma align 4 (blah)
#pragma pack(1)
/* i also tried putting the align pragma at this place */
     struct { long y; short x; char z; } blah;
#pragma pack()
     blah.x = blah.y = blah.z = 1;

     return 0;

Quote:}

This has absolutely no effect, sun cc is ignoring whatever alignment i
request and keep placing blah at a 2-byte aligned address and not at a
properly aligned address.

At this point i think it's about getting time looking through the sun
forte manuals, and i do indeed find something interesting in the forte 7
developer c++ users guide:

"When using #pragma pack on a SPARC platform to pack denser than the
type's default alignment, the -misalign option must be specified for
both the compilation and the linking of the application. The following
table shows the storage sizes and default alignments of the integral
data types."

So i compile my little test program with -misalign and yes, it runs
properly now. Glad as i am i look up the description for the -misalign
switch and while reading it i'm stunned. -misalign is an absolutely
horrible solution to this problem. It turns out that -misalign is equal
to -xmemalign=1i and the meaning of this option is that an exception
handler for misalignment exceptions is to be installed which does
interpretes the access of the misaligned address in software and let's
the program continue as if nothing happened.

Obviously this is *horribly* inefficient, this takes orders of
magnitudes more cycles than simply using unaligned load/store sequences
to access the packed structure in the first place. This is the worst
possible solution one can possibly think of in dealing with misaligned
access for this particular case.

So i found one more solution which does the trick, but which is really
really ugly:

int main() {
     union {
         long align;
#pragma pack(1)
         struct { long y; short x; char z; } a;
#pragma pack()
     } blah;

     blah.a.x = blah.a.y = blah.a.z = 1;
     return 0;

Quote:}

the 'long align' in the union guarantees that the blah structure is
properly aligned to the natural alignment of long (this is guaranteed by
the ansi c standard). However, this is not an acceptable solution really.

So my question is, are there any better ways to deal with this? Any
things i'm overlooking?

Any input is highly appreciated!

Regards,
        - Jogchem

P.S.

To get a valid email address to answer by mail, simply reverse the part

 
 
 

Alignment issues with Sun C Compiler

Post by Seongbae Par » Thu, 04 Mar 2004 07:01:15



> Hello,

> I have some serious problems with the pack() pragma with sun cc:

> I'd like to have the members of a few structures packed. That is without
> any additional (compiler-dependent) padding between the members so that
> it can be used for binary communication with other systems. To
> accomplish this i surrounded the declaration of my structure with the
> pack pragma:

> int main() {
> #pragma pack(1)
>      struct { short x; long y; char z; } blah;
> #pragma pack()
>      blah.x = blah.y = blah.z = 1;

>      return 0;
> }

> This indeed seems to pack the structure, however accessing the members
> generates a misalignment exception (SIGBUS):

> (from dbx)

> signal BUS (invalid address alignment) in main at line 6 in file "k.c"
>      6      blah.x = blah.y = blah.z = 1;

> Ok, i would have expected the compiler to schedule (synthesized,
> consisting out of 2 loads/stores + shift + or to load/store from an
> abitrary address) unaligned load/store instructions to access the fields
> of this packed structure.. Well, i thought, there would be an easy
> solution: By providing a different structure layout where the members
> requiring the highest alignment are placed first and in order this
> problem could be solved:

> int main() {
> #pragma pack(1)
>      struct { long y; short x; char z; } blah;
> #pragma pack()
>      blah.x = blah.y = blah.z = 1;

>      return 0;
> }

> Sadly this does not solve the problem, i get again a SIGBUS, some closer
> inspection with dbx shows that the starting address of 'blah' is
> misaligned itself.. I would have expected the compiler to align the
> whole structure at least on the natural alignment of the first member
> which would in this case be sizeof(long):

> signal BUS (invalid address alignment) in main at line 5 in file "k.c"
>      5       blah.x = blah.y = blah.z = 1;
> (dbx) print &blah
> &blah = 0xffbff37d

> Obviously as you can see the address of blah is not aligned on a 4-byte
> (sizeof(long) == 4 on sparcv8) alignment and this is causing the
> alignment exception.

> My third attempt is to explicitly tell the compiler what alignment i want:

> int main() {
> #pragma align 4 (blah)
> #pragma pack(1)
> /* i also tried putting the align pragma at this place */
>      struct { long y; short x; char z; } blah;
> #pragma pack()
>      blah.x = blah.y = blah.z = 1;

>      return 0;
> }

> This has absolutely no effect, sun cc is ignoring whatever alignment i
> request and keep placing blah at a 2-byte aligned address and not at a
> properly aligned address.

From Sun ONE Studio 8 C User's Guide:

    ...
    Note that when you use #pragma pack, the alignment of the packed
    structure or union itself is the same as its more strictly
    aligned member. Therefore any declaration of that struct or union
    will be at the pack alignment.

- Show quoted text -

Quote:> At this point i think it's about getting time looking through the sun
> forte manuals, and i do indeed find something interesting in the forte 7
> developer c++ users guide:

> "When using #pragma pack on a SPARC platform to pack denser than the
> type's default alignment, the -misalign option must be specified for
> both the compilation and the linking of the application. The following
> table shows the storage sizes and default alignments of the integral
> data types."

> So i compile my little test program with -misalign and yes, it runs
> properly now. Glad as i am i look up the description for the -misalign
> switch and while reading it i'm stunned. -misalign is an absolutely
> horrible solution to this problem. It turns out that -misalign is equal
> to -xmemalign=1i and the meaning of this option is that an exception
> handler for misalignment exceptions is to be installed which does
> interpretes the access of the misaligned address in software and let's
> the program continue as if nothing happened.
> Obviously this is *horribly* inefficient, this takes orders of
> magnitudes more cycles than simply using unaligned load/store sequences
> to access the packed structure in the first place. This is the worst
> possible solution one can possibly think of in dealing with misaligned
> access for this particular case.

You can use -xmemalign=1s which will force the compiler
to use byte load/store.

- Show quoted text -

Quote:> So i found one more solution which does the trick, but which is really
> really ugly:

> int main() {
>      union {
>          long align;
> #pragma pack(1)
>          struct { long y; short x; char z; } a;
> #pragma pack()
>      } blah;

>      blah.a.x = blah.a.y = blah.a.z = 1;
>      return 0;
> }

> the 'long align' in the union guarantees that the blah structure is
> properly aligned to the natural alignment of long (this is guaranteed by
> the ansi c standard). However, this is not an acceptable solution really.

> So my question is, are there any better ways to deal with this? Any
> things i'm overlooking?

The current best bet is to have all functions that access packed structure
to be compiled with -xmemalign=1s.

Seongbae

 
 
 

Alignment issues with Sun C Compiler

Post by Joerg Schilli » Thu, 04 Mar 2004 08:52:55




>Hello,

>I have some serious problems with the pack() pragma with sun cc:

>I'd like to have the members of a few structures packed. That is without
>any additional (compiler-dependent) padding between the members so that
>it can be used for binary communication with other systems. To
>accomplish this i surrounded the declaration of my structure with the
>pack pragma:

>int main() {
>#pragma pack(1)
>     struct { short x; long y; char z; } blah;
>#pragma pack()
>     blah.x = blah.y = blah.z = 1;

>     return 0;
>}

>This indeed seems to pack the structure, however accessing the members
>generates a misalignment exception (SIGBUS):

This looks like badly designed software inherited from x86 guys....

Writing code like this is very bad prectice that completely depends on
processor specifics.

Only do it if you need to do this because you need to match specific hardware
or if you need to write files that expect such a format.

#define i_to_2_byte(a, i)       (((Uchar *)(a))[0] = ((i) >> 8) & 0xFF,\
                                    ((Uchar *)(a))[1] = (i) & 0xFF)

int main() {
        struct {
                char    xs[2];
                char    yl[4];
                char    zc;
        } blah;

        i_to_2_byte(bla.xs, 1)

     return 0;

Quote:}

See more include/intcvt.h in cdrtools

ftp://ftp.berlios.de/pub/cdrecord/alpha/

--



URL:  http://www.fokus.fraunhofer.de/usr/schilling ftp://ftp.berlios.de/pub/schily

 
 
 

Alignment issues with Sun C Compiler

Post by Casper H.S. Di » Fri, 05 Mar 2004 00:06:17



>I'd like to have the members of a few structures packed. That is without
>any additional (compiler-dependent) padding between the members so that
>it can be used for binary communication with other systems. To
>accomplish this i surrounded the declaration of my structure with the
>pack pragma:

Note that there are more problems than just alignment: anything longer
than a single byte is likely represented differently on different machines.

Quote:>This indeed seems to pack the structure, however accessing the members
>generates a misalignment exception (SIGBUS):

You need to compile/link with an additional option to generate unaligned
accesses.

Quote:>So i found one more solution which does the trick, but which is really
>really ugly:
>int main() {
>     union {
>         long align;
>#pragma pack(1)
>         struct { long y; short x; char z; } a;
>#pragma pack()
>     } blah;

There doesn't seem to be a reason to back this structure except for the
padding at the end; in this case there is no padding between the members.

Casper
--
Expressed in this posting are my opinions.  They are in no way related
to opinions held by my employer, Sun Microsystems.
Statements on Sun products included here are not gospel and may
be fiction rather than truth.

 
 
 

1. Alignment issues using the Sun C++ compiler SC4.2

You don't want to mess with aligment, if you use it to
exchange data, you're barking up the wrong tree.
Checkout XDR instead and find that tehre's much more than
aligment to data exchange.

And when it comes to C++ classes, forget about exchanging
those between unlike systems, the compilers will wildly disagree
about how classes are laid out.

There's a pragma pack, but after that your code wil run slowly.

Casper
--
Expressed in this posting are my opinions.  They are in no way related
to opinions held by my employer, Sun Microsystems.
Statements on Sun products included here are not gospel and may
be fiction rather than truth.

2. (u)dma/hdparm question

3. SUN and FSF C++ compiler issues...

4. Tape copy problems

5. Sun C++ compiler issue...

6. ld: virtual memory exhausted

7. Issues with Sun's C++ Compiler

8. linux vs freebsd

9. Are sun studio C/C++ compilers and Forte C/C++ compilers same ??

10. The sun Compiler directive with the SUNspro compiler

11. Compiler alignment and network problem.

12. C for AIX Compiler - Issues/Bugs

13. C++ Compiler version and issues on TRU64 5.1A (upgrading from V4.0D)