GNU C語法擴充套件(10)

要研究LINUX核心,C語言是基礎中的基礎,但是LINUX並不是完全的標準C,而是對標準C做了很多擴充套件,這些擴充套件特性對於我們分析核心有著很重要的作用,下面做些總結性的工作。
10、內建函式
GNU C提供了大量的內建函式,其中很多是標準C庫函式的內建版本,例如memcpy,它們與對應的C庫函式功能相同,本文不討論這類函式,其他內建函式的名字通常以__builtin開始。
-
內建函式
__builtin_return_address(LEVEL)
返回當前函式或其呼叫者的返回地址,引數LEVEL指定呼叫棧的級數,如0表示當前函式的返回地址,1表示當前函式呼叫者的返回地址,依此類推。例如:
//kernel/sched.c printk(KERN_ERR "schedule_timeout: wrong timeout" "value %lx from %p\n", timeout, __builtin_return_address(0));
- 內建函式
__builtin_constant_p(EXP)
用於判斷一個值是否為編譯時常數,如果引數EXP的值是常數,函式返回1,否則返回0。
//include /asm-i386/bitops.h #define test_bit(nr,addr)/ (__builtin_constant_p(nr)?/ constant_test_bit( (nr),(addr) ):/ variable_test_bit( (nr),(addr) ) )
很多計算或操作在引數為常數時有更優化的實現,在GNUC中用上面的方法可以根據引數是否為常數,只編譯常數版本或非常數版本,這樣既不失通用性,又能在引數是常數時編譯出最優化的程式碼。
- 內建函式
__builtin_expect(EXP, C)
用於為編譯器提供分支預測資訊,其返回值是整數表示式EXP的值,C的值必須是編譯時常數。例如:
//include /linux/compiler.h #define likely(x) __builtin_expect((x),1) #define unlikely(x) __builtin_expect((x),0) //kernel/sched.c if( unlikely(in_interrupt()) ){ printk("Schedulingininterrupt/n"); BUG(); }
這個內建函式的語義是EXP的預期值是C,編譯器可以根據這個資訊適當地重排語句塊的順序,使程式在預期的情況下有更高的執行效率。上面的例子表示處於中斷上下文是很少發生的,第6-7行的目標碼可能會放在較遠的位置,以保證經常執行的目標碼更緊湊。
若不想使用GNUC擴充套件,那麼只需要在gcc引數後面加上-ansi-pedantic即可,使用上述引數後,所有GNCC擴充套件語法部分將會有編譯警報。
更多知識:
點選關注專題: 嵌入式Linux & ARM
或瀏覽器開啟: https://www.jianshu.com/c/42d33cadb1c1
或掃描二維碼:
