Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6974873
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 27, 20262026-05-27T17:17:39+00:00 2026-05-27T17:17:39+00:00

In C, the compiler will lay out members of a struct in the order

  • 0

In C, the compiler will lay out members of a struct in the order in which they’re declared, with possible padding bytes inserted between members, or after the last member, to ensure that each member is aligned properly.

gcc provides a language extension, __attribute__((packed)), which tells the compiler not to insert padding, allowing struct members to be misaligned. For example, if the system normally requires all int objects to have 4-byte alignment, __attribute__((packed)) can cause int struct members to be allocated at odd offsets.

Quoting the gcc documentation:

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.

Obviously the use of this extension can result in smaller data requirements but slower code, as the compiler must (on some platforms) generate code to access a misaligned member a byte at a time.

But are there any cases where this is unsafe? Does the compiler always generate correct (though slower) code to access misaligned members of packed structs? Is it even possible for it to do so in all cases?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-27T17:17:39+00:00Added an answer on May 27, 2026 at 5:17 pm

    Yes, __attribute__((packed)) is potentially unsafe on some systems. The symptom probably won’t show up on an x86, which just makes the problem more insidious; testing on x86 systems won’t reveal the problem. (On the x86, misaligned accesses are handled in hardware; if you dereference an int* pointer that points to an odd address, it will be a little slower than if it were properly aligned, but you’ll get the correct result.)

    On some other systems, such as SPARC, attempting to access a misaligned int object causes a bus error, crashing the program.

    There have also been systems where a misaligned access quietly ignores the low-order bits of the address, causing it to access the wrong chunk of memory.

    Consider the following program:

    #include <stdio.h>
    #include <stddef.h>
    int main(void)
    {
        struct foo {
            char c;
            int x;
        } __attribute__((packed));
        struct foo arr[2] = { { 'a', 10 }, {'b', 20 } };
        int *p0 = &arr[0].x;
        int *p1 = &arr[1].x;
        printf("sizeof(struct foo)      = %d\n", (int)sizeof(struct foo));
        printf("offsetof(struct foo, c) = %d\n", (int)offsetof(struct foo, c));
        printf("offsetof(struct foo, x) = %d\n", (int)offsetof(struct foo, x));
        printf("arr[0].x = %d\n", arr[0].x);
        printf("arr[1].x = %d\n", arr[1].x);
        printf("p0 = %p\n", (void*)p0);
        printf("p1 = %p\n", (void*)p1);
        printf("*p0 = %d\n", *p0);
        printf("*p1 = %d\n", *p1);
        return 0;
    }
    

    On x86 Ubuntu with gcc 4.5.2, it produces the following output:

    sizeof(struct foo)      = 5
    offsetof(struct foo, c) = 0
    offsetof(struct foo, x) = 1
    arr[0].x = 10
    arr[1].x = 20
    p0 = 0xbffc104f
    p1 = 0xbffc1054
    *p0 = 10
    *p1 = 20
    

    On SPARC Solaris 9 with gcc 4.5.1, it produces the following:

    sizeof(struct foo)      = 5
    offsetof(struct foo, c) = 0
    offsetof(struct foo, x) = 1
    arr[0].x = 10
    arr[1].x = 20
    p0 = ffbff317
    p1 = ffbff31c
    Bus error
    

    In both cases, the program is compiled with no extra options, just gcc packed.c -o packed.

    (A program that uses a single struct rather than array doesn’t reliably exhibit the problem, since the compiler can allocate the struct on an odd address so the x member is properly aligned. With an array of two struct foo objects, at least one or the other will have a misaligned x member.)

    (In this case, p0 points to a misaligned address, because it points to a packed int member following a char member. p1 happens to be correctly aligned, since it points to the same member in the second element of the array, so there are two char objects preceding it — and on SPARC Solaris the array arr appears to be allocated at an address that is even, but not a multiple of 4.)

    When referring to the member x of a struct foo by name, the compiler knows that x is potentially misaligned, and will generate additional code to access it correctly.

    Once the address of arr[0].x or arr[1].x has been stored in a pointer object, neither the compiler nor the running program knows that it points to a misaligned int object. It just assumes that it’s properly aligned, resulting (on some systems) in a bus error or similar other failure.

    Fixing this in gcc would, I believe, be impractical. A general solution would require, for each attempt to dereference a pointer to any type with non-trivial alignment requirements either (a) proving at compile time that the pointer doesn’t point to a misaligned member of a packed struct, or (b) generating bulkier and slower code that can handle either aligned or misaligned objects.

    I’ve submitted a gcc bug report. As I said, I don’t believe it’s practical to fix it, but the documentation should mention it (it currently doesn’t).

    UPDATE: As of 2018-12-20, this bug is marked as FIXED. The patch will appear in gcc 9 with the addition of a new -Waddress-of-packed-member option, enabled by default.

    When address of packed member of struct or union is taken, it may
    result in an unaligned pointer value. This patch adds
    -Waddress-of-packed-member to check alignment at pointer assignment and warn unaligned address as well as unaligned pointer

    I’ve just built that version of gcc from source. For the above program, it produces these diagnostics:

    c.c: In function ‘main’:
    c.c:10:15: warning: taking address of packed member of ‘struct foo’ may result in an unaligned pointer value [-Waddress-of-packed-member]
       10 |     int *p0 = &arr[0].x;
          |               ^~~~~~~~~
    c.c:11:15: warning: taking address of packed member of ‘struct foo’ may result in an unaligned pointer value [-Waddress-of-packed-member]
       11 |     int *p1 = &arr[1].x;
          |               ^~~~~~~~~
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

According to here , the C compiler will pad out values when writing a
I want to dynamically add .Select statements, but the compiler will only allow me
As expected, the compiler (VisualStudio 2008) will give a warning warning C4715: 'doSomethingWith' :
If I omit the operators from statement, something like this: while(foo) will the compiler
(1). When using C++ template, is it correct that the compiler (e.g. g++) will
I am now studying C++. I want a makefile which will compile all of
Sometimes Android SDK compiling Project will generate an empty layout XML named main.out.xml ,
I'm trying to add a dialog box which will pop up when a user
Possible Duplicate: Structure of a C++ Object in Memory Vs a Struct memory layout
I've noticed that my C compiler (gcc) will let me do stuff like: #include

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.