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
#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
相关文章推荐
- Linux命令之文件系统(九)
- Linux命令之文件系统(八)
- linux下scrapy环境搭建
- Linux系统的启动流程
- 19个心得 明明白白说Linux下的负载均衡
- Linux命令之文件系统(七)
- linux下查看网关的命令
- Linux命令经典面试题:统计文件中出现次数最多的前10个单词
- linux下看懂CPU
- CentOS 下配置软RAID(Software RAID)CentOS 下配置LVM(逻辑卷管理)
- 解决克隆centos虚拟机后ip配置失败的问题
- Linux笔记(43)——文件特殊权限
- linux上查找文件存放地点和文件中查找字符串方法
- 用U盘安装CentOS6.5系统
- linux命令:查找文件
- Linux进程与线程概述
- Linux sed Examples--转载
- linux权限命令
- linux-debug-with log file
- Linux命令之文件系统(六)