1.零长度数组

GNU C允许使用零长度数组,定义变长度对象时比较方便

struct var_data {

int len;

char data[0];

};

var_data的大小仅为一个int型,data是常量地址,data[index]是访问其后的内存空间。

struct var_data *s = malloc(sizeof(var_data) + len);

释放内存的时候free(s)只释放int,所以还要认为地释放data空间,这会带来不便。另外只有GNU C支持,c/c++编译永远通不过。

2.case范围

GNU C支持case x...y这样的语法,区间[x ,y]都满足这个条件。例如

case 0...5 ==> case 0 : case 1: case 2: case 3: case 4: case 5:

3.语句表达式

GNU C可以把括号中的复合语句看成是语句表达式, a=( ; ; ),于是就有了以下应用

#define min_t(type, x, y) ((type __x  = (x); typ __y = (y); __x < __y ? __x : __y;))

float minf  = min_t(float, f1, f2);

int mini  = min_t(int, i1, i2);

4.typeof关键字

typeof(x)语句可以获得x的类型

5.可变参数的宏

标准C只支持可变参数的函数

int printf(const char *format [, argument]...);

而GNU C也支持可变参数的宏

#define pr_debug(fmt, arg...)   printfk(fmt, ##arg)

6.标号元素

标准C要求数组或结构体的初始值必须以固定顺序出现,而GNU C可以通过指定索引和结构体成员允许初始化值以任意顺序出现([index] = ),当然也可以如下运用

unsigned char data[MAX] = {[0...MAX - 1] = 0};

下面是借助结构体成员名初始化值

struct file_operations ext2_file_operation = {

llseek: generic_file_llseek,

read: generic_file_read,

write:generic_file_write,

ioctl:ext2_ioctl,

mmap:generic_file_mmap,

open:generic_file_open,

release:ext2_release_file,

fsync:ext2_sync_file,

};

但是linux2.6推荐类似的代码应该尽量采用标准C的语法

struct file_operations ext2_file_operation = {

.llseek  =  generic_file_llseek,

.read    =   generic_file_read,

.write    =   generic_file_write,

.ioctl     =    ext2_ioctl,

.mmap =   generic_file_mmap,

.open   =generic_file_open,

.release  = ext2_release_file,

.fsync      =  ext2_sync_file,

};

7.当前函数名

GNU C预定义了两个标识符保存当前函数的名字,__FUNCTION__保存函数在源码中的名字,__PRETTY_FUNCTION__保存带语言特色的名字,而标注C两者是一样的。

void exampe()

{

printf("This is function %s\n", __FUNCTION__);

}

8.特殊属性声明

GNU C允许声明函数,变量和类型的特殊属性,以便进行手工优化和定制代码检查的方法。指定一个属性只需在其声明后添加__attribute__((ATTRIBUTE)).

noreturn 属性作用于函数,表示该函数从不反悔。这回让编译器优化代码,并消除不必要的警告信息。

例如:void do_exit(int n) __attribute__((noreturn));

format属性也用于函数,该函数使用printf、scanf或strftime风格的参数,指定format属性可以让编译器根据格式串检查参数类型。

unused属性作用于函数和变量,表示该函数或变量可能不会被用到,这个属性可以避免编译器产生警告信息。

aligned属性用于变量、结构体或联合体,指定变量、结构体或联合体的对齐方式,以字节为单位。

例如:struct example_struct{

char a;

int b;

long c;

} __attribute__((aligned(4)));表示该结构类型的变量以4字节对齐。

packed属性作用于变量和类型,用于变量和结构体成员时表示使用最小可能的对齐,用于枚举、结构体或联合体类型时表示该类型使用最小的内存。

例如:struct example_struct{

char a;

int b;

long c __attribute__((packed));

} ;

9.内建函数

GNU C除了标准C提供的内建函数(memcpy)外,还提供了许多其他的内建函数,通常命名以__builtin开始。

__builtin_return_address(LEVEL)返回当前函数或调用这的返回地址,参数LEVEL指定调用栈的级数,如0表示当前函数的返回地址,1表示当前函数的调用者的返回地址。

__builtin_constant_p(EXP)用于判断一个值是否为编译时常数,是返回1,否则返回0.例如下面的代码检测第一个参数是否为常数以确定采用参数版本还是非参数版本

#define test_bit(nr, addr) (__builtin_constant_p(nr) ? constant_test_bit((nr), (addr)) : variable_test_bit((nr), (addr))

——记《linux设备驱动开发详解》宋宝华

GNU C 与 ANSI C的区别的更多相关文章

  1. linux内核中GNU C和标准C的区别

    linux内核中GNU C和标准C的区别 今天看了一下午的linux内核编程方面的内容,发现linux 内核中GNU C与标准C有一些差别,特记录如下: linux 系统上可用的C编译器是GNU C编 ...

  2. GNU C 、ANSI C、标准C、标准c++区别和联系

    转载自点击打开链接 GNU计划,又称革奴计划,是由Richard Stallman在1983年9月27日公开发起的.它的目标是创建一套完全自由的操作系统.它在编写linux的时候自己制作了一个标准成为 ...

  3. GNU C 与 ANSI C(下)

    1. 语句表达式 GNU C 把包含在括号中的复合语句看做是一个表达式,称作语句表达式,它可以出现在任何允许表达式的地方.我们可以在语句表达式中使用原本只能在复合语句中使用的循环.局部变量等,例如: ...

  4. GNU C 与 ANSI C(上)

    Linux 上可用的 C 编译器是 GNU C 编译器,它建立在自由软件基金会的编程许可证的基础上,因此可以自由发布.GNU C 是对标准 C 进行的一系列扩展,以增强标准 C 的功能. 1. 零长度 ...

  5. GNU C与ANSI C的不同

    引用:http://tsroad.lofter.com/post/376316_57ac519 1.GNU C可定义0长度数组,目的是为了定义可变长结构体. struct var_struct{    ...

  6. 字符编码ANSI和ASCII区别、Unicode和UTF-8区别

    ANSI码ANSI编码是一种对ASCII码的拓展:ANSI编码用0x00~0x7f (即十进制下的0到127)范围的1 个字节来表示 1 个英文字符,超出一个字节的 0x80~0xFFFF 范围来表示 ...

  7. C11 (GNU Dialect) -std=gnu11 和 -std=c11

    C11 (GNU Dialect) -std=gnu11 和 -std=c11 C11 (GNU Dialect) -std=gnu11 和 -std=c11 用于 IntelliSense 的 C ...

  8. ANSI码和UNICODE码

    什么是ANSI,什么又是UNICODE呢? 其实这是两种不同的编码方式标准,ANSI中的字符采用8bit,而UNICODE中的字符采用16bit. (对于字符来说ANSI以单字节存放英文字符,以双字节 ...

  9. GCC、g++编译器和gcc编译器的区别

    GCC:(GNU Compiler Collection,GNU编译器套件),是由 GNU 开发的编程语言编译器.它是以GPL许可证所发行的自由软件,也是 GNU计划的关键部分. gcc:GNU的C语 ...

随机推荐

  1. 20 ViewPager demo5,6:FragmentAdapter 导航数据

    Demo5 文件结构: MainActivity.java package com.qf.day20_viewpager_demo5; import java.util.ArrayList; impo ...

  2. 集合框架之Queue接口

    Queue接口 在处理元素前用于保存元素的 collection.除了基本的 Collection 操作外,队列还提供其他的插入.提取和检查操作.每个方法都存在两种形式:一种抛出异常(操作失败时),另 ...

  3. Swift中类似C++和ruby中的final机制

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 我们知道在C++和ruby语言的错误处理中有一种final机制 ...

  4. JDBC的使用五大步骤以及查询操作-数据库编程(二)

    jdbc的使用步骤 1.加载jdbc的驱动. 2.打开数据库的连接. 3.建立一个会话,然后执行增删改查等基本的操作. 4.对结果进行处理 5.对环境进行清理,比如关闭会话等. 查询操作 首先用Cla ...

  5. Android反编译 -- 错误代码还原

    PS:如果阅读体验不好,可以尝试Github版 (<-点左边) 1. setColor(-16777216) 反编译的代码中会有很多setColor(int)的情况,比如setColor(-16 ...

  6. 01_MyBatis EHCache集成及所需jar包,ehcache.xml配置文件参数配置及mapper中的参数配置

     1 与mybatis集成时需要的jar ehcache-core-2.6.5.jar mybatis-ehcache-1.0.2.jar Mybatis.日志.EHCache所需要的jar包如下 ...

  7. UNIX网络编程——客户/服务器程序设计示范(五)

        TCP预先派生子进程服务器程序,传递描述符 对预先派生子进程服务器程序的最后一个修改版本是只让父进程调用accept,然后把所接受的已连接套接字"传递"给某个子进程.这么做 ...

  8. 秒懂ASP.NET中的内置对象

    上篇博客,小编主要简单的介绍了一下ASP.NET中的控件,这篇博客,小编主要简单总结一下ASP.NET中的内置对象,七个内置对象分别是:Request.Response.Application.Coo ...

  9. 如何在Cocos2D 1.0 中掩饰一个精灵(六)

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 掩饰一个精灵:实现代码 打开HelloWorldLayer.m并 ...

  10. 分布式进阶(二)Ubuntu 14.04下安装Dockr图文教程(一)

    当前,完全硬件虚拟化技术(KVM.Xen.Hyper-V 等)能在一个物理主机上很好地运行多个互相独立的操作系统,但这也带来一些问题:性能不佳,资源浪费,系统反应迟缓等.有时候对用户来说,完全的硬件虚 ...