Thread: Force 1 byte alignement in 32 bit system

  1. #1
    Registered User bremenpl's Avatar
    Join Date
    Apr 2013
    Posts
    57

    Force 1 byte alignement in 32 bit system

    Hello there,
    I am trying to force my 32 bit system to align my struct with bytes not words...
    This is my struct:
    Code:
    typedef struct
    {
        uint8_t             tolerance;
        uint8_t             footprint[24];
        uint8_t             value[24];
        uint8_t             comment[100];
        uint8_t             type[24];
        uint8_t             pitch;
        uint8_t             rotation;
    } fppStruct_t;
    
    typedef union
    {
        fppStruct_t            fppStruct;
        uint8_t                fppArray[sizeof(fppStruct_t)]; // 175
    } feederPartParam_t;
    I am using __packed=__attribute__((__packed__)) in symbols.

    When I do:
    Code:
    (sizeof(feederPartParam_t)
    I get 175 like i thought I would (1+24+24+100+24+1+1).
    But when I do (feeder is an object of type feederPartParam*):
    Code:
    feeder->fPartParams.fppStruct.tolerance = 10;
        feeder->fPartParams.fppStruct.footprint[0] = 1;
    I thought my array would get populated like this:
    Code:
    feeder->fPartParams.fppStruct.fppArray[0] = 10;
    feeder->fPartParams.fppStruct.fppArray[1] = 1;
    feeder->fPartParams.fppStruct.fppArray[2] = 0;
    ...
    Instead I get some weird padding:
    Code:
    feeder->fPartParams.fppStruct.fppArray[0] = 10;
    feeder->fPartParams.fppStruct.fppArray[1] = 0;
    feeder->fPartParams.fppStruct.fppArray[2] = 1;
    ...
    It skips one byte. Is there a way to make the padding one byte? I dont quite understand because the struct size is correct but padding is wrong. I would apreciate all help!

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I do not seem able to reproduce your problem with gcc 4.8.4 on Ubuntu 14.04 64-bit:
    Code:
    #include <stdio.h>
    #include <stdint.h>
    
    #define NUMBERS_PER_ROW 20
    
    typedef struct __attribute__((__packed__))
    {
        uint8_t tolerance;
        uint8_t footprint[24];
        uint8_t value[24];
        uint8_t comment[100];
        uint8_t type[24];
        uint8_t pitch;
        uint8_t rotation;
    } fppStruct_t;
     
    typedef union
    {
        fppStruct_t fppStruct;
        uint8_t     fppArray[sizeof(fppStruct_t)];
    } feederPartParam_t;
    
    int main(void)
    {
        printf("%zu %zu\n-------\n", sizeof(fppStruct_t), sizeof(feederPartParam_t));
        feederPartParam_t feeder = {{0}};
        feeder.fppStruct.tolerance = 10;
        feeder.fppStruct.footprint[0] = 1;
        for (size_t i = 0; i < sizeof(fppStruct_t); ++i)
        {
            printf("%2u ", feeder.fppArray[i]);
            if (i % NUMBERS_PER_ROW == NUMBERS_PER_ROW - 1)
            {
                printf("\n");
            }
        }
        printf("\n");
        return 0;
    }
    when compiled with -std=c99 and run gives the output:
    Code:
    175 175
    -------
    10  1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
     0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
     0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
     0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
     0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
     0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
     0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
     0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
     0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
    Actually, let this be an example for you to follow: notice that instead of saying "feeder is an object of type feederPartParam*", I declared feeder to be a feederPartParam_t object, i.e., I simplified since the pointer was unnecessary: in fact, your statement made no sense as there is no such type as feederPartParam, so there is no such type as feederPartParam*.

    Instead of saying that "It skips one byte" while showing code that would have made that happen, I showed code that printed out the array for inspection, and then showed the output that demonstrated that it did not skip one byte.

    This way, if I did something contrary to what you did, you can more easily spot it, whereas with your "tell without showing" approach, we have to either assume that you wrote the correct code (in which case why do you need help?), or guess at what went wrong.
    Last edited by laserlight; 12-22-2015 at 04:07 AM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User bremenpl's Avatar
    Join Date
    Apr 2013
    Posts
    57
    I understand. next time I will try to create more showing examples, sorry. I got the values read from debugger.

    I am using an arm crosscompiller from Atolic:
    Code:
    gcc version 4.8.3 20140228 (release) [ARM/embedded-4_8-branch revision 208322] (GNU Tools for ARM Embedded Processors (Build 14.09 Pro))
    I will try to work some more on it.

    I have used your example with locally created variable and it worked out the same as for you... I am not sure why.
    Last edited by bremenpl; 12-22-2015 at 04:18 AM.

  4. #4
    Registered User bremenpl's Avatar
    Join Date
    Apr 2013
    Posts
    57
    I think I know what is the case... I have an array of sctructs created like this:
    Code:
    feederObject_t* rs485_feederBlock = 0;
    ...
    size_t blockByteSize = config_globalFlash.flashStruct.nrOfFeeders * sizeof(feederObject_t); // x * 175
    rs485_feederBlock = malloc(blockByteSize);
    assert_param(rs485_feederBlock);
    I fear malloc is making bad alignement, but I am using symbol __packed=__attribute__((__packed__)) so thats weird. feederPartParam_t is one of the members of feederObject_t.
    Last edited by bremenpl; 12-22-2015 at 04:47 AM.

  5. #5
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    I think you may be interested in this link.

    From that link:
    Q: What is structure alignment?
    A: All modern CPUs expect that fundamental types like ints, longs and floats will be stored in memory at addresses that are multiples of their length.
    CPUs are optimized for accessing memory aligned in this way.
    Some CPUs:
    allow unaligned access but at a performance penalty;
    trap unaligned accesses to the operating system where they can either be ignored, simulated or reported as errors;
    use unaligned addresses as a means of doing special operations during the load or store.

    When a C compiler processes a structure declaration, it can:
    add extra bytes between the fields to ensure that all fields requiring alignment are properly aligned;
    ensure that instances of the structure as a whole are properly aligned. Malloc always returns memory pointers that are aligned for the strictest, fundamental machine type.
    Jim

  6. #6
    Registered User bremenpl's Avatar
    Join Date
    Apr 2013
    Posts
    57
    Thank you.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 4
    Last Post: 10-23-2011, 08:18 AM
  2. File Comparision byte by byte
    By anusha2489 in forum C Programming
    Replies: 12
    Last Post: 05-16-2011, 06:58 AM
  3. windows system() call return codes shifted by one byte?
    By leonv in forum Windows Programming
    Replies: 2
    Last Post: 02-19-2011, 01:59 PM
  4. reading files byte by byte
    By cpsc in forum C++ Programming
    Replies: 12
    Last Post: 01-07-2011, 03:54 PM
  5. TIFF IFD byte by byte
    By ghostcoder in forum C++ Programming
    Replies: 4
    Last Post: 12-21-2010, 04:33 PM