今天看《C專家編程》第7章第8節,最后提到用setjmp/longjmp從信號終恢復。順便敲了代碼看看效果,就對其中jmp_buf這個結構感興趣。查看一下,發現/usr/include/setjmp.h
中是這么定義的:
![2015-11-30 23-12-46屏幕截圖.png-47.7kB][1]
圖1
另外__jmp_buf
的定義在/usr/include/i386-linux-gnu/bits/setjmp.h
:
![2015-11-30 23-43-23屏幕截圖.png-25.4kB][2]
圖2
圖1定義方式很奇怪,即將一個結構定義成由一個成員的數組,剛開始不理解為什么,上網搜了一下,發現2005年云風大神已經有博客了。
文章講得很簡略,細細一想,發現了其中的奧秘:
其實這個小的trick主要利用了C語言中數組的性質:我們假設定義jmp_buf buf;
- 我們用jmp_buf定義一個變量的時候,相當于定義了一個只有一個成員的數組(按照typedef,jmp_buf數據類型就是一個數組類型,因此用它定義的變量也是數組,只不過這個數組比較特殊,數組的成員是一個結構);我們知道定義數組的時候,編譯器會分配內存,那么我們定義這個變量大小就是
sizeof(jmp_buf)
。 - 我們知道數組名在直接傳遞的時候會退化成指針,因此可以起到傳址的作用。
鏈接文章中提到在聲明的時候可以把數據分配到堆棧(stack)上,我想說,這樣就是利用上面提到的。假設我們在一個函數里面聲明一個變量,那么變量會被壓入stack中,而傳遞參數或者訪問結構的時候傳遞指針就可以了。
這就是數組的兩頭都占好的特性吧,定義時候能直接分配好地址,使用的時候還能把數組名當指針用。
再參考:
setjmp 的正確使用
[1]: http://static.zybuluo.com/yiltoncent/hsbtp6mt7mzlv4m2pu57s287/2015-11-30%2023-12-46%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE.png
[2]: http://static.zybuluo.com/yiltoncent/0j8w3iyif6icqpnvja6rddmz/2015-11-30%2023-43-23%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE.png