Linux 內核 gcc 宏 container_of 的語法問題?
container_of宏裡面被兩個分號跟著的2句命令中,第二句明顯就是一個數值,他是怎麼吧第二句的數值傳回到上面調用這個宏的變數pos中的,但是怎麼感覺語法不對啊,
等同於這個: int b,c;c={b=5;(int)3;};這個也編譯不了,語法錯誤。
#include &
int main() {
int a = 0;
int b = 1;
int c = 0;
c = ({
a = b;
b = 3;
});
printf ("%d
", c);
}
$ ./block
3
講的是,告訴你一個struct他某個field的指針是多少,求struct的指針。就是個減法的事情。然而你還可以看到,由於沒有C++的一些語法,gcc還自己發明了一些奇怪的、跟C標準不兼容、跟C++長得也不一樣的語法。
譬如typeof(fuck),譬如({fuck})。
由於Linux代碼採用Gcc編譯器編譯,所以它可以採用Gcc對C語言的擴展特性,以實現高效的代碼。其中運用非常廣泛的擴展就是複合語句。Gcc把包含在圓括弧和大括弧雙層括弧內的複合語句看作是一個表達式,它可以出現在任何允許表達式的地方,而複合語句中可以聲明局部變數,以及循環條件判斷等複雜處理。而表達式的最後一條語句必須是一個表達式,它的計算結果作為返回值。
int a = ({typeof(a) _a = 0; ++_a;});
上例中符合表達式中聲明了局部變數_a,而返回值為++_a的結果,所以a的值為1。基於這種擴展,內核可以通過在複合語句中定義局部變數而避免自加自減運算符所帶來的副作用問題。
#define square(a) ((a)*(a))
int i = 10;
int j = square(++i);
這裡由於展開後,變成了((++i)*(++i)),i會自加兩次,而這不是我們所期待的。將宏定義部分先賦值給安全變數,然後對安全變數進行操作可以避免此類問題。
內核中的min_t和max_t宏就是這樣實現的。如果不這樣做,調用min(a++,b++)就會帶來一些問題。include/linux/kernel.h
#define min_t(type, x, y) ({
type __min1 = (x);
type __min2 = (y);
__min1 &< __min2 ? __min1: __min2; })
#define max_t(type, x, y) ({
type __max1 = (x);
type __max2 = (y);
__max1 &> __max2 ? __max1: __max2; })
我來挖墳。
這個是GCC自己搞出來的一套東西,算是GCC對C語言的擴展
https://gcc.gnu.org/onlinedocs/gcc-5.1.0/gcc/Statement-Exprs.html#Statement-Exprs除了這個還有好多黑魔法。。推薦閱讀:
※中斷,異常,陷阱,軟硬中斷,同非同步中斷??
※為什麼Linux內核代碼鮮有中國人的貢獻?
※linux內核中,對於字元設備/塊設備/匯流排/設備/驅動等概念,如何正確理解?
※全局變數什麼時候在內存中申請空間呢?
※linux CFS調度演算法的疑問?