1.指定内存默认对其参数:

__attribute__((packed)):按一字节对其
__attribute__((aligned(n))):从此之后默认按n字节对其
例如:

struct stu
{
  int a;
  char b;
}__attribute__((packed));
struct stu
{
  int a __attribute__((aligned()));
  char b;
};

例子:

#include <stdio.h>

struct ss
{
char a __attribute__((aligned()));
int b;//① __attribute__((aligned(16)));
};//②__attribute__((aligned(16))); void main()
{
int i;
printf("%d\n", sizeof(struct ss));
struct ss s1 = {0x11, 0x55443322}; unsigned char *p = (unsigned char *)&s1; for(i=; i<sizeof(s1); i++)
{
printf("0x%x\n", *(p+i));
}
}
输出: 0x11
0xd1
0x98
0x0
0x22
0x33
0x44
0x55
0xe0
0xfc
0x98
0x0
0xf4
0xef
0x98
0x0

可以看出:

__attribute__((aligned(16)))在哪个域后面修饰哪个域(注意仅对此域有效,对其它域无效),更改了这个域的实际对齐参数,实际对齐参数决定了此域的起始存储位置,
再结合结构体的总大小必须能整除每一个域的最大对齐参数,因此可以推出来结构体的大小和内存的存储关系。
将结构体中注释掉掉的部分加上结构体大小就是32字节。

若只要③处,设定的只是结构体间对齐,结构体成员的存储顺序不变,只是结构体变长了。

1.1、结构体中含有位段的情况

#include <stdio.h>

struct S3_1
{
char a;
short b : ;
short c : ;
short d : ;
int e : ;
int f : ;
}; struct S3_1 s3 = {0x11, , , , 0xf, 0x3f}; void main()
{
int i; printf("sizeof(s3)= %d\n", sizeof(s3)); unsigned char *p = (char *)&s3; for(i=; i<sizeof(s3); i++)
{
printf("0x%x\n", *(p+i));
}
}
①GNU的gcc编译器和Windows里的编译器的结果不一样,GNU的gcc输出:
sizeof(s3)=
0x11
0xff
0x3f
0x0
即最后面的int型的位段页归并到short里面一起用了。 ②在Window上gcc软件编译出输出:
sizeof(s3)=
0x11
0x0
0xf
0x0
0xff
0x3
0x0
0x0
和一般结构体对齐类似,只是其中的位是不是都占用而已。

2.__attribute__((weak))指定一个函数是若函数,消除链接时的multiple definition

例如:main.c
#include <stdio.h>
#define __weak __attribute__((weak))
void __weak func(void)
{
  printf("%s\n", "void __atribute__(weak) func(void)");
}
void main()
{
  func();
}
test.c中
#include <stdio.h>
void func(void)
{
  printf("%s\n", "void func(void)");
}

3.__attribute__((regparm(0))):告诉gcc编译器该函数不需要通过任何寄存器来传递参数,参数只是通过堆栈来传递。
__attribute__((regparm(3))):告诉gcc编译器这个函数可以通过寄存器传递多达3个的参数,x86PC上,这3个寄存器依次为EAX、EDX 和 ECX。更多的参数才通过堆栈传递。这样可以减少一些入栈出栈操作,因此调用比较快。 ARM核默认是多于4个参数的会被保存在栈中

4.函数没有使用的参数后加__unused可防止编译器报警告

/*加上"__unused"可以防止编译器报警告:warning: unused parameter 'id' [-Wunused-parameter]*/
int led_module_open(const struct hw_module_t* module, const char* id __unused, struct hw_device_t** device) {
......
}

gcc的编译属性和选项的更多相关文章

  1. GCC编译命令常用选项

    GCC是GUN Compiler Collection的简称,除编译程序外,还包含其他相关工具.GCC可将高级语言编写的源代码构建成计算机直接执行的二进制代码.GCC是Linux平台下最常用的编译程序 ...

  2. 利用gcc的__attribute__编译属性section子项构建初始化函数表【转】

    转自:https://my.oschina.net/u/180497/blog/177206 gcc的__attribute__编译属性有很多子项,用于改变作用对象的特性.这里讨论section子项的 ...

  3. Gcc的编译流程分为了四个步骤:

    http://blog.csdn.net/xiaohouye/article/details/52084770(转) Gcc的编译流程分为了四个步骤: 1.预处理,生成预编译文件(.文件): Gcc ...

  4. [vim配置]windows下在vim中使用gcc/g++编译调试c/cpp文件

    在Linux里面混了一个多月,vim编程用得甚爽.无奈前天将Linux里面的编程文件夹误删,而技术不精无法找回,悲痛欲绝.再者,无限怀念windows里面的游戏,并觉得现在在Linux里面也学不到什么 ...

  5. GCC的编译和安装 很好的资料

    http://blog.csdn.net/yrj/article/details/492404 1.GCC的编译和安装2.预处理    #define 可以支持不定数量的参数.    例子如下:    ...

  6. Linux-编译器gcc/g++编译步骤

    gcc和g++现在是gnu中最主要和最流行的c&c++编译器.g++是c++的命令,以.cpp为主:对于c语言后缀名一般为.c,这时候命令换做gcc即可.编译器是根据gcc还是g++来确定是按 ...

  7. GCC(警告.优化以及调试选项)

    GCC(警告.优化以及调试选项) [介绍] gcc and g++分别是gnu的c & c++编译器   gcc/g++在执行编译工作的时候,总共需要4步   1.预处理,生成.i的文件 预处 ...

  8. 学习总结:gcc/g++ 编译与链接

    gcc/g++ 编译与链接 编译与链接的过程可以分解为四个步骤:预处理.编译.汇编.链接 预处理:源代码文件和相关的头文件,被预处理器cpp预处理成一个后缀为 .i 的文件(选项:-E) 编译:把预处 ...

  9. Nginx的编译安装及选项

    编译安装Nginx1.安装常见的工具和库(GCC.PCRE.zlib.OpenSSL) Nginx是一个由C语言编写的,所以需要一个编译工具如GNU的GCC[root@www ~]# yum inst ...

随机推荐

  1. maven scope和项目发布需要注意的地方

    Maven Scope的使用: http://www.cnblogs.com/wangyonghao/p/5976055.html servlet-api和jsp-api等jar包,一般由servle ...

  2. form 表单模板

    <div class="modal-dialog modal-lg"> //大布局modal-lg <div class="modal-content& ...

  3. 使用DevExpress Reports和PDF Viewer创建AcroForm Designer

    众所周知,交互式表单(AcroForms)是PDF标准的重要组成部分,AcroForms允许开发者和开发者的用户创建可填写的PDF文档.尽管WinForms和WPF PDF Viewers不支持交互式 ...

  4. ios 第4天

    dealloc method  会在对象释放前调用这个方法(函数)  可以让对象在释放前把一些自己申请的对象 先释放了    满足 谁申请  谁释放 的原则 例如    dealloc 会自动调用   ...

  5. 原生js封装tap

    // tap事件封装function tap(obj, callBack){ if(typeof obj != 'object') return; // 变量 var startTime = 0; / ...

  6. 20165326 java第六周学习笔记

    第六周学习总结 ch8 String类对于有效处理字符序列信息非常重要. String对象的字符序列不能被修改删除,无法发生变化. StringBuffer类的对象实体的内存空间可以自动改变大小,便于 ...

  7. 终止TTask.Run启动的线程

    unit Unit15; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, Syste ...

  8. python 基础-爬虫-数据处理,全部方法

    生成时间戳 1. time.time() 输出 1515137389.69163 ===================== 生成格式化的时间字符串 1. time.ctime() 输出 Fri Ja ...

  9. 将numpy array由浮点型转换为整型

    使用numpy中的astype()方法可以实现,示例如下: x Out[20]: array([[ 5. , 4. ], [ 4. , 4.33333333], [ 3.66666667, 4.5 ] ...

  10. SQL注入之Sqli-labs系列第二十四关(二阶注入)

    开始挑战第二十四关(Second Degree Injections) 0x1 前言 SQL注入一般分为两类:一阶SQL注入(普通SQL注入),二阶SQL注入 .二次注入不是注入两次的意思,请不要混淆 ...