日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

GNU C是什么?

GNU C建立在自由軟件基金會的編程許可證的基礎(chǔ)上,因此可以自由發(fā)布。GNU C對標(biāo)準(zhǔn)C進行進一步擴展,以增強標(biāo)準(zhǔn)C的功能。

特別是嵌入式軟件開發(fā)過程中,經(jīng)常會遇到很多GNU C的語法,以為是C語言沒學(xué)過關(guān),其實很多都不是標(biāo)準(zhǔn)C語言中的語法。哈哈!

 

擴展差異

1、零長度數(shù)組

GNU C 允許使用零長度數(shù)組,在定義變長對象的頭結(jié)構(gòu)時,這個特性非常有用。例如:

struct minix_dir_entry { 
   __u16 inode; 
   char name[0];
};

結(jié)構(gòu)的最后一個元素定義為零長度數(shù)組,它不占結(jié)構(gòu)的空間。在標(biāo)準(zhǔn) C 中則需要定義數(shù)組長度為 1,分配時計算對象大小比較復(fù)雜。

 

2、case范圍
GNU C 允許在一個 case 標(biāo)號中指定一個連續(xù)范圍的值,例如:

case '0' ... '9': c -= '0'; break; 
case 'a' ... 'f': c -= 'a'-10; break; 
case 'A' ... 'F': c -= 'A'-10; break;

其中case '0' ... '9': 相當(dāng)于 case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':


3、語句表達式
GNU C 把包含在括號中的復(fù)合語句看做是一個表達式,稱為語句表達式,它可以出現(xiàn)在任何允許表達式的地方,你可以在語句表達式中使用循環(huán)、局部變量等,原本只能在復(fù)合語句中使用。例如:

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

復(fù)合語句的最后一個語句應(yīng)該是一個表達式,它的值將成為這個語句表達式的值。這里定義了一個安全的求最小值的宏,在標(biāo)準(zhǔn) C 中,通常定義為:

#define min(x,y) ((x) < (y) ? (x) : (y))

這個定義計算 x 和 y 分別兩次,當(dāng)參數(shù)有副作用時(比如出現(xiàn)參數(shù)自增或自減語句時),將產(chǎn)生不正確的結(jié)果,使用語句表達式只計算參數(shù)一次,避免了可能的錯誤。語句表達式通常用于宏定義。


4、typeof關(guān)鍵字
使用前一節(jié)定義的宏需要知道參數(shù)的類型,利用 typeof 可以定義更通用的宏,不必事先知道參數(shù)的類型,例如:

#define min(x,y) ({  
  const typeof(x) _x = (x);     
  const typeof(y) _y = (y);     
  (void) (&_x == &_y);           
_x < _y ? _x : _y; })

這里 typeof(x) 表示 x 的值類型, const typeof(x) _x = (x); 中定義了一個與 x 類型相同的局部變量 _x 并初使化為 x, (void) (&_x == &_y); 的作用是檢查參數(shù) x 和 y 的類型是否相同。typeof 可以用在任何類型可以使用的地方,通常用于宏定義。


5、可變參數(shù)的宏
在 GNU C 中,宏可以接受可變數(shù)目的參數(shù),就象函數(shù)一樣,例如:

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

這里 arg 表示其余的參數(shù),可以是零個或多個,這些參數(shù)以及參數(shù)之間的逗號構(gòu)成 arg 的值,在宏擴展時替換 arg,例如:

pr_debug("%s:%d",filename,line)

會被擴展為

printk("%s:%d", filename, line)

使用 ## 的原因是處理 arg 不匹配任何參數(shù)的情況,這時 arg 的值為空,GNU C 預(yù)處理器在這種特殊情況下,丟棄 ## 之前的逗號,這樣

pr_debug("success!n")

會被擴展為

printk("success!n")

而不是printk("success!n",)
注意最后的逗號。


6、標(biāo)號元素
標(biāo)準(zhǔn) C 要求數(shù)組或結(jié)構(gòu)變量的初使化值必須以固定的順序出現(xiàn),在 GNU C 中,通過指定索引或結(jié)構(gòu)域名,允許初始化值以任意順序出現(xiàn)。指定數(shù)組索引的方法是在初始化值前寫 '[INDEX] =',要指定一個范圍使用 '[FIRST ... LAST] =' 的形式,例如:

static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL };

將數(shù)組的所有元素初使化為 ~0UL,這可以看做是一種簡寫形式。
要指定結(jié)構(gòu)元素,在元素值前寫 'FIELDNAME:',例如:

struct file_operations ext2_file_operations = { 
     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, 
};

將結(jié)構(gòu) ext2_file_operations 的元素 llseek 初始化為 generic_file_llseek,元素 read 初始化為 genenric_file_read,依次類推。我覺得這是 GNU C 擴展中最好的特性之一,當(dāng)結(jié)構(gòu)的定義變化以至元素的偏移改變時,這種初始化方法仍然保證已知元素的正確性。對于未出現(xiàn)在初始化中的元素,其初值為 0。


7、當(dāng)前函數(shù)名
GNU CC 預(yù)定義了兩個標(biāo)志符保存當(dāng)前函數(shù)的名字,__FUNCTION__ 保存函數(shù)在源碼中的名字,__PRETTY_FUNCTION__ 保存帶語言特色的名字。在 C 函數(shù)中,這兩個名字是相同的,在 C++ 函數(shù)中,__PRETTY_FUNCTION__ 包括函數(shù)返回類型等額外信息,linux 內(nèi)核只使用了 __FUNCTION__。

void example()
{
  printf{“This is function:%s”, __FUNCTION__};
}

代碼中__FUNCTION__意味著字符串“example”。


8、特殊屬性聲明
GNU C 允許聲明函數(shù)、變量和類型的特殊屬性,以便手工的代碼優(yōu)化和更仔細的代碼檢查。要指定一個聲明的屬性,在聲明后寫 __attribute__ (( ATTRIBUTE ))其中 ATTRIBUTE 是屬性說明,多個屬性以逗號分隔。GNU C 支持十幾個屬性,這里介紹最常用的:

noreturn
屬性 noreturn 用于函數(shù),表示該函數(shù)從不返回。這可以讓編譯器生成稍微優(yōu)化的代碼,最重要的是可以消除不必要的警告信息比如未初使化的變量。例如:

# define ATTRIB_NORET   __attribute__((noreturn)).... 
asmlinkage NORET_TYPE void do_exit(long error_code) ATTRIB_NORET;

format
屬性 format 用于函數(shù),表示該函數(shù)使用 printf, scanf 或 strftime 風(fēng)格的參數(shù),使用這類函數(shù)最容易犯的錯誤是格式串與參數(shù)不匹配,指定 format 屬性可以讓編譯器根據(jù)格式串檢查參數(shù)類型。例如:

asmlinkage int printk(const char * fmt, ...)    __attribute__ ((format (printf, 1, 2)));

表示第一個參數(shù)是格式串,從第二個參數(shù)起根據(jù)格式串檢查參數(shù)。
unused
屬性 unused 用于函數(shù)和變量,表示該函數(shù)或變量可能不使用,這個屬性可以避免編譯器產(chǎn)生警告信息。
aligned
屬性 aligned 用于變量、結(jié)構(gòu)或聯(lián)合類型,指定變量、結(jié)構(gòu)域、結(jié)構(gòu)或聯(lián)合的對齊量,以字節(jié)為單位,例如:

struct example_struct
{
 char a;
 int   b;
 long c;
} __attribute__((aligned(4)));

表示該結(jié)構(gòu)類型的變量以4字節(jié)對界。
packed
屬性 packed 用于變量和類型,用于變量或結(jié)構(gòu)域時表示使用最小可能的對齊,用 于枚舉、結(jié)構(gòu)或聯(lián)合類型時表示該類型使用最小的內(nèi)存。例如:

struct example_struct
{
   char a;
   int b__attribute__ ((packed));
   long c__attribute__((packed));
};

對于結(jié)構(gòu)體example_struct而言,在i386平臺下,其sizeof的結(jié)果為9,如果刪除其中的2個—attribute__((packed)),其sizeof將為12.


9、內(nèi)建函數(shù)
GNU C 提供了大量的內(nèi)建函數(shù),其中很多是標(biāo)準(zhǔn) C 庫函數(shù)的內(nèi)建版本,例如memcpy,它們與對應(yīng)的 C 庫函數(shù)功能相同,不屬于庫函數(shù)的其他內(nèi)建函數(shù)的名字通常以 __builtin 開始。例如:


__builtin_return_address (LEVEL)
內(nèi)建函數(shù) __builtin_return_address 返回當(dāng)前函數(shù)或其調(diào)用者的返回地址,參數(shù) LEVEL 指定在棧上搜索框架的個數(shù),0 表示當(dāng)前函數(shù)的返回地址,1 表示當(dāng)前函數(shù)的調(diào)用者的返回地址,依此類推。


__builtin_constant_p(EXP)
內(nèi)建函數(shù) __builtin_constant_p 用于判斷一個值是否為編譯時常數(shù),如果參數(shù)EXP 的值是常數(shù),函數(shù)返回 1,否則返回 0。


__builtin_expect(EXP, C)
內(nèi)建函數(shù) __builtin_expect 用于為編譯器提供分支預(yù)測信息,其返回值是整數(shù)表
達式 EXP 的值,C 的值必須是編譯時常數(shù)。
例如,下面的代碼檢測第一個參數(shù)是否為編譯時常數(shù)以確定采用參數(shù)版本還是非參數(shù)版本代碼:

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

分享到:
標(biāo)簽:GNU
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運動步數(shù)有氧達人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定