您的位置:首页 > 运维架构 > Linux

Linux下的 arm-linux-gcc 与 gcc 关于字节对齐问题

2016-03-15 17:08 603 查看
__attrubte__ ((packed)) 的作用就是告诉编译器取消结构在编译过程中的优化对齐,按照实际占用字节数进行对齐。

#define __u8    unsigned char

#define __u16   unsigned short

/* __attribute__ ((packed)) 的位置约束是放于声明的尾部“;”之前 */

struct str_struct{

        __u8    a;

        __u8    b;

        __u8    c;

        __u16   d;

} __attribute__ ((packed));

/*  当用到typedef时,要特别注意__attribute__ ((packed))放置的位置,相当于:

  *  typedef struct str_stuct str;

  *  而struct str_struct 就是上面的那个结构。

  */

typedef struct {

        __u8    a;

        __u8    b;

        __u8    c;

        __u16   d;

} __attribute__ ((packed)) str;

/* 在下面这个typedef结构中,__attribute__ ((packed))放在结构名str_temp之后,其作用是被忽略的,注意与结构str的区别。*/

typedef struct {

        __u8    a;

        __u8    b;

        __u8    c;

        __u16   d;

}str_temp __attribute__ ((packed));

typedef struct {

        __u8    a;

        __u8    b;

        __u8    c;

        __u16   d;

}str_nopacked;

int main(void)

{

        printf("sizeof str_struct   = %d/n", sizeof(struct str_struct));

        printf("sizeof str          = %d/n", sizeof(str));

        printf("sizeof str_temp      = %d/n", sizeof(str_temp));

        printf("sizeof str_nopacked = %d/n", sizeof(str_nopacked));

        return 0;

}

编译运行:

[root@localhost root]# ./packedtest   

sizeof str_struct   = 5 
sizeof str          = 5

sizeof str_temp      = 6

sizeof str_nopacked = 6

--------------------------------------------------------------------

GNU C的一大特色就是__attribute__机制。__attribute__可以设置函数属性(Function Attribute)、变量属性(Variable Attribute)和类型属性(Type Attribute)。

__attribute__书写特征是:__attribute__前后都有两个下划线,并且后面会紧跟一对括弧,括弧里面是相应的__attribute__参数。

__attribute__语法格式为:

__attribute__ ((attribute-list))

其位置约束:放于声明的尾部“;”之前。

函数属性(Function Attribute):函数属性可以帮助开发者把一些特性添加到函数声明中,从而可以使编译器在错误检查方面的功能更强大。__attribute__机制也很容易同非GNU应用程序做到兼容之功效。

GNU CC需要使用 –Wall编译器来击活该功能,这是控制警告信息的一个很好的方式。

packed属性:使用该属性可以使得变量或者结构体成员使用最小的对齐方式,即对变量是一字节对齐,对域(field)是位对齐。

 

//--补充

今天移植usb驱动到uboot中,就发现这个问题。在ads1.2中用__packed修饰的,我一开始把它去掉了。搞了2天没搞出来。后来才发现是这个问题。

方法一:

#include <stdio.h>

#pragma pack(1)
struct abc
{
    double
a;
    int    b;
    char   c;
};
#pragma pack()

void main()
{
    printf(
"sizeof( struct abc ) = %d\n", sizeof( struct abc ) );
}

以上代码
gcc tBytePadding.c -o tBytePadding
Ubuntu执行结果:sizeof( struct abc ) = 13

/usr/local/arm/2.95.3/bin/arm-linux-gcc -I /usr/local/arm/2.95.3/arm-linux/include tBytePadding.c -o tBytePadding
执行结果:sizeof( struct abc ) = 16 <-- 依然四字对齐了,没有一字节对齐

方法二:

#include <stdio.h>

typedef struct tagabc
{
    double a;
    int    b;
    char   c;
}__attribute__( ( packed, aligned( 1 ) ) ) abc;

void main()
{
    printf( "sizeof( abc ) = %d\n", sizeof( abc ) );
}



#include <stdio.h>

struct abc
{
    double
a;
    int    b;
    char   c;
}__attribute__( ( packed, aligned(1)
) )
;

void main()
{
    printf(
"sizeof( struct abc ) = %d\n", sizeof( struct abc ) );
}

以上代码
gcc tBytePadding.c -o tBytePadding
Ubuntu执行结果:sizeof( struct abc ) = 13

/usr/local/arm/2.95.3/bin/arm-linux-gcc -I /usr/local/arm/2.95.3/arm-linux/include tBytePadding.c -o tBytePadding
执行结果:sizeof( struct abc ) = 13

推荐使用方法二的第一种!

注意:
typedef struct tagabc
{
    double
a;
    int    b;
    char   c;
}__attribute__( ( packed, aligned( 1 ) ) );

tagabc abc;

以上写法会报此错误:warning: ‘packed’ attribute
ignored


typedef struct tagabc
{
    double
a;
    int    b;
    char   c;
} abc __attribute__( ( packed, aligned( 1 ) ) );

以上写法也会报此错误:warning: ‘packed’
attribute ignored
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: