Find the answer to your Linux question:
Page 1 of 2 1 2 LastLast
Results 1 to 10 of 12
Hi All, How can I disable structure alignment feature of gcc using command-line options ? I recently migrated to 64-bit OS, and doubt that I might be experiencing a structure ...
  1. #1
    Just Joined!
    Join Date
    Nov 2009
    Posts
    43

    Question how to disable structure alignment using gcc compiler options ?

    Hi All,

    How can I disable structure alignment feature of gcc using command-line options ?

    I recently migrated to 64-bit OS, and doubt that I might be experiencing a structure alignment problem due to the new 64-bit architecture.

    I checked the sizes of the same C-style struct in both x86 and x86_64, and found out that they appear to be different by 20 bytes.

    I am not sure if this is due to structure alignment or the differences in data type lengths between two platforms.

    Hence, I will first disable the structure alignment feature, and then check the struct sizes again.

    Thanks.

  2. #2
    Linux Enthusiast gerard4143's Avatar
    Join Date
    Dec 2007
    Location
    Canada, Prince Edward Island
    Posts
    714
    Could we see an example of one of the structures..
    Make mine Arch Linux

  3. #3
    Just Joined!
    Join Date
    Nov 2009
    Posts
    43
    Quote Originally Posted by gerard4143 View Post
    Could we see an example of one of the structures..
    Sure. You can find it below:

    Code:
    struct msg{
      long int mtype;
    
      long int configRefreshed;
    
      int sizeName;
      int sizePName;
      int sizeCName;
    
      int sizeANo;
      int sizeY;
      int sizeM;
      int sizeD;
      int sizeH;
      int sizeM;
    
      int sizeData;
    
      char pName[16];
      char appPName[16]; 
      char appCName[16]; 
    
      char aNo[40];
      char y[5]; 
      char m[2]; 
      char d[2]; 
      char h[2]; 
      char m[2];
    
      struct timeval ts;
      u_char Data[1500];
    };
    The length of this struct is 1660 in 32-bit OS using sizeof().

    On the other hand, it is 1680 in 64-bit OS.

    Considering I am casting (C-style cast) from u_char* (this is a network data) to struct msg in multiple places in my source code, it seems to be possible to read wrong data.

    I should have used absolute-length data types instead ?

  4. #4
    Linux Enthusiast KenJackson's Avatar
    Join Date
    Jun 2006
    Location
    Maryland, USA
    Posts
    506
    Try compiling and running this program on both machines:
    Code:
    #include <stdio.h>
    #include <sys/time.h>
    int main(int argc, char *argv[])
    {
        printf("int is %u bytes, long is %u bytes, timeval is %u bytes\n",
               sizeof(int), sizeof(long), sizeof(struct timeval));
    }

  5. #5
    Just Joined!
    Join Date
    Aug 2007
    Posts
    2
    Quote Originally Posted by aryan_ View Post
    Sure. You can find it below:

    Code:
    struct msg{
      long int mtype;
    
      long int configRefreshed;
    
      int sizeName;
      int sizePName;
      int sizeCName;
    
      int sizeANo;
      int sizeY;
      int sizeM;
      int sizeD;
      int sizeH;
      int sizeM;
    
      int sizeData;
    
      char pName[16];
      char appPName[16]; 
      char appCName[16]; 
    
      char aNo[40];
      char y[5]; 
      char m[2]; 
      char d[2]; 
      char h[2]; 
      char m[2];
    
      struct timeval ts;
      u_char Data[1500];
    };
    The length of this struct is 1660 in 32-bit OS using sizeof().

    On the other hand, it is 1680 in 64-bit OS.

    Considering I am casting (C-style cast) from u_char* (this is a network data) to struct msg in multiple places in my source code, it seems to be possible to read wrong data.

    I should have used absolute-length data types instead ?
    __________________________________________________ _________-
    You don't give any reason for wanting to over-rule gcc's probably entirely reasonable defaults. x86_64 has native support for aligned 64-bit ints. If you wished to minimize the requirement for padding which is likely to differ between 32- and 64-bit mode, you would have followed the legacy rule of placing your struct components in decreasing order of size, and always multiples of native data type sizes.
    If you write binary files in one mode, and read in another mode, yes, you risk breaking it, as you might expect. You do have the option of gcc packed attributes, if you consider those appropriate, but it looks like you would have to add explicit padding if the purpose is to match what you did most recently in 32-bit mode.

  6. #6
    Just Joined!
    Join Date
    Jul 2008
    Posts
    1

    Smile packed structures

    Here is how you can turn off alignment with compiler directives.


    #define packed_data __attribute__((__packed__))

    struct msg{
    long int mtype;

    long int configRefreshed;

    int sizeName;
    int sizePName;
    int sizeCName;

    int sizeANo;
    int sizeY;
    int sizeM;
    int sizeD;
    int sizeH;
    int sizeM;

    int sizeData;

    char pName[16];
    char appPName[16];
    char appCName[16];

    char aNo[40];
    char y[5];
    char m[2];
    char d[2];
    char h[2];
    char m[2];

    struct timeval ts;
    u_char Data[1500];
    }packed_data;

  7. #7
    Just Joined!
    Join Date
    Nov 2009
    Posts
    43
    Quote Originally Posted by KenJackson View Post
    Try compiling and running this program on both machines:
    Code:
    #include <stdio.h>
    #include <sys/time.h>
    int main(int argc, char *argv[])
    {
        printf("int is %u bytes, long is %u bytes, timeval is %u bytes\n",
               sizeof(int), sizeof(long), sizeof(struct timeval));
    }
    The output on 32-bit is:

    Code:
    int is 4 bytes, long is 4 bytes, timeval is 8 bytes
    The output on 64-bit is:

    Code:
    int is 4 bytes, long is 8 bytes, timeval is 16 bytes

  8. #8
    Linux Enthusiast KenJackson's Avatar
    Join Date
    Jun 2006
    Location
    Maryland, USA
    Posts
    506
    Quote Originally Posted by aryan_ View Post
    The output on 32-bit is:

    Code:
    int is 4 bytes, long is 4 bytes, timeval is 8 bytes
    The output on 64-bit is:

    Code:
    int is 4 bytes, long is 8 bytes, timeval is 16 bytes
    OK! There's 16 of the 20 bytes difference: the 2 longs are each 4 bytes longer, and the timeval is 8 bytes longer. The remaining 4 bytes difference is likely the padding that the others referred to.

    My guess is, if you change your longs to ints and move the timeval above the date, the result will be only an 8-byte difference due to the difference in timeval. If you want to get rid of that, don't use timeval--store the equivalent information in ints and regenerate it as needed.

  9. #9
    Just Joined!
    Join Date
    Nov 2009
    Posts
    43
    Quote Originally Posted by KenJackson View Post
    My guess is, if you change your longs to ints and move the timeval above the date, the result will be only an 8-byte difference due to the difference in timeval.
    What part do you mean by "date" in "move the timeval above the date" ?

  10. #10
    Linux Enthusiast KenJackson's Avatar
    Join Date
    Jun 2006
    Location
    Maryland, USA
    Posts
    506
    Quote Originally Posted by aryan_ View Post
    What part do you mean by "date" in "move the timeval above the date" ?
    y[5], m[2], d[2], h[2], m[2].

    I assume those are year, month, etc. That's 13 bytes--which is not a multiple of 4 or 8. The compiler will add padding bytes between those fields and the timeval to move it to the right boundary.

    But if you move it yourself, the compiler wont' need to add any padding. That's what tprince was talking about when he referenced rule of placing your struct components in decreasing order of size.

Page 1 of 2 1 2 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
...