在跨平台C语言编程中,数据对齐是一个要着重注意的问题。对于结构体(struct)中数据的对齐方式一般来说大家都已经很熟悉了,这里要讨论的是不同编译器对数组字节的对齐问题。
先看一段代码:

#include <stdio.h>
#include <stdint.h>
#include <string.h>

int main(){
    uint8_t data[3];

    memset(data,0,3);
    uint16_t *data_odd = (uint16_t *)(data+1);
    *data_odd = 0x5566;
    printf("%x %x %x n",data[0],data[1],data[2]);
}

这段代码执行的是一个数据填充的功能,将数组的后两个字节填充为一个16位的数据0×5566。在PC上用GCC编译运行上面的代码,得到的输出为:

0 66 55

这个输出是符合期望的。(注:0×5566以little endian方式存储于内存中)

然而,用arm-linux-gcc编译运行以上代码时,得到了不同的输出:

66 55 0

出现这种情况的原因是,由于效率上的考虑,某些编译器会对一些特定数据会从特定地址进行存取,比如在这里对16位类型的数据编译器必须从偶数地址开始存取,若不是偶数地址会默认采取前挪的动作。因此数据往前移了一个字节。这种错误比较隐蔽往往难以发现,解决方法就是严格按字节进行存取。
在跨平台C语言编程中,对字节的存取应尤其小心,力求准确,否则就会像我一样调这种bug调了一天(望天

If you enjoyed this post, make sure you subscribe to my RSS feed!
Tagged with:
 

8 Responses to Data alignment in cross-platform C programming

  1. Sunng says:

    这个是syntax error: Unexpected EOF.

  2. Push says:

    碰到这种问题直接

    #pragma pack(1)
    typedef union tagUXXX
    {
        struct {
            // ...
        };
        unsigned char ...;
    } UXXX ;
    #pragma pack()

    了…已经懒得去纠结对齐了…

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Set your Twitter account name in your settings to use the TwitterBar Section.