-D_REENTRANT
在一個(gè)多線程程序里鬼廓,默認(rèn)情況下,只有一個(gè)errno變量供所有的線程共享致盟。在一個(gè)線程準(zhǔn)備獲取剛才的錯(cuò)誤代碼時(shí)碎税,該變量很容易被另一個(gè)線程中的函數(shù)調(diào)用所改變。類似的問題還存在于fputs之類的函數(shù)中馏锡,這些函數(shù)通常用一個(gè)單獨(dú)的全局性區(qū)域來緩存輸出數(shù)據(jù)雷蹂。
為解決這個(gè)問題,需要使用可重入的例程杯道》嘶停可重入代碼可以被多次調(diào)用而仍然工作正常。編寫的多線程程序党巾,通過定義宏_REENTRANT來告訴編譯器我們需要可重入功能萎庭,這個(gè)宏的定義必須出現(xiàn)于程序中的任何#include語句之前。
_REENTRANT為我們做三件事情昧港,并且做的非常優(yōu)雅:
(1)它會(huì)對(duì)部分函數(shù)重新定義它們的可安全重入的版本擎椰,這些函數(shù)名字一般不會(huì)發(fā)生改變支子,只是會(huì)在函數(shù)名后面添加_r字符串创肥,如函數(shù)名gethostbyname變成gethostbyname_r
(2)stdio.h中原來以宏的形式實(shí)現(xiàn)的一些函數(shù)將變成可安全重入函數(shù)。
(3)在error.h中定義的變量error現(xiàn)在將成為一個(gè)函數(shù)調(diào)用值朋,它能夠以一種安全的多線程方式來獲取真正的errno的值
-w
-w的意思是關(guān)閉編譯時(shí)的警告叹侄,也就是編譯后不顯示任何warning,因?yàn)橛袝r(shí)在編譯之后編譯器會(huì)顯示一些例如數(shù)據(jù)轉(zhuǎn)換之類的警告昨登,這些警告是我們平時(shí)可以忽略的趾代。
-Wall
-Wall選項(xiàng)意思是編譯后顯示所有警告。
-W
-W選項(xiàng)類似-Wall丰辣,會(huì)顯示警告撒强,但是只顯示編譯器認(rèn)為會(huì)出現(xiàn)錯(cuò)誤的警告。
在編譯一些項(xiàng)目的時(shí)候可以-W和-Wall選項(xiàng)一起使用笙什。
-D_FILE_OFFSET_BITS
打開文件后用 fseek()函數(shù)把文件位置指針移動(dòng)到文件的末尾飘哨,用 ftell()獲得這時(shí)位置指針距文件頭的字節(jié)數(shù),這個(gè)字節(jié)數(shù)就是文件的長度琐凭。但是這樣做也會(huì)受到下面的限制:ftell()函數(shù)的返回值是 long 類型芽隆,在Windows 下(不管是 32 位還是 64 位),long 類型變量的長度都是 4 字節(jié),這樣能正常獲取到的文件長度必須小于 2GB.
微軟在 Visual Studio 2005 及以后版本的開發(fā)工具中胚吁,在 stdio.h 中提供了函數(shù) _fseeki64()和 _ftelli64()牙躺。_fseeki64()函數(shù)中表示文件指針偏移量的變量是 __int64 類型,_ftelli64()的返回值也是 __int64 類型腕扶,因此可以用這兩個(gè)函數(shù)獲取大文件(指超過 2GB)的長度孽拷。
注意 Linux 和 Unix 中的 C 編譯器沒有提供 _fseeki64()和 _ftelli64()函數(shù),但是在 stdio.h 中提供了 fseeko()和 ftello()函數(shù)蕉毯,fseeko()函數(shù)中表示文件指針的偏移量的變量是 off_t 類型乓搬,ftello()的返回值也是off_t 類型,off_t 類型的長度有可能是 32 比特或 64 比特代虾,使用宏定義 #define _FILE_OFFSET_BITS 64 可以將 off_t 設(shè)為64 比特長进肯。
-O 優(yōu)化級(jí)別
-O參數(shù)只有5個(gè)級(jí)別,并不是設(shè)置的越高越好(以前的GCC支持很高的級(jí)別棉磨,但是現(xiàn)在確實(shí)只有5級(jí))
-O0:關(guān)閉所有優(yōu)化選項(xiàng)
-O1:基本優(yōu)化江掩,編譯器會(huì)生成更快的代碼
-O2:-O1的升級(jí)版,推薦使用
-O3:這是目前最高的優(yōu)化級(jí)別乘瓤,它會(huì)使用更多的編譯時(shí)間环形,雖然它生成的代碼只會(huì)比-O2塊一點(diǎn)點(diǎn)(GCC3.x中是這樣的,但是在GCC4.x中有時(shí)候可能還沒有-O2快)衙傀,但是它會(huì)增大二進(jìn)制文件的體積并讓他們更消耗內(nèi)存抬吟,因此在GCC4.x中-O3是不推薦的。
-Os:這個(gè)級(jí)別是用來優(yōu)化代碼尺寸的统抬,他只是給一些CPU緩存或是磁盤空間小的機(jī)器使用
-O0: 無優(yōu)化火本。
-O和-O1: 使用能減少目標(biāo)代碼尺寸以及執(zhí)行時(shí)間并且不會(huì)使編譯時(shí)間明顯增加的優(yōu)化。在編譯大型程序的時(shí)候會(huì)顯著增加編譯時(shí)內(nèi)存的使用聪建。
-O2: 包含-O1的優(yōu)化并增加了不需要在目標(biāo)文件大小和執(zhí)行速度上進(jìn)行折衷的優(yōu)化钙畔。編譯器不執(zhí)行循環(huán)展開以及函數(shù)內(nèi)聯(lián)。此選項(xiàng)將增加編譯時(shí)間和目標(biāo)文件的執(zhí)行性能金麸。
-Os: 可以看成 -O2.5擎析,專門優(yōu)化目標(biāo)文件大小,執(zhí)行所有的不增加目標(biāo)文件大小的-O2優(yōu)化選項(xiàng)挥下,并且執(zhí)行專門減小目標(biāo)文件大小的優(yōu)化選項(xiàng)揍魂。適用于磁盤空間緊張時(shí)使用。但有可能有未知的問題發(fā)生棚瘟,況且目前硬盤容量很大现斋,常用程序無必要使用。
-O3: 打開所有 -O2 的優(yōu)化選項(xiàng)外增加 -finline-functions解取、-funswitch-loops步责、-fgcse-after-reload 優(yōu)化選項(xiàng)。相對(duì)于 -O2 性能并未有較多提高,編譯時(shí)間也最長蔓肯,生成的目標(biāo)文件也更大更占內(nèi)存遂鹊,有時(shí)性能不增反而降低,甚至產(chǎn)生不可預(yù)知的問題(包括錯(cuò)誤)蔗包,所以并不被大多數(shù)軟件安裝推薦秉扑,除非有絕對(duì)把握方可使用此優(yōu)化級(jí)別。
修改GCC編譯參數(shù)调限,提高編譯優(yōu)化級(jí)別舟陆,此方法適用于所有通過GCC編譯安裝的程序,不止Nginx耻矮。穩(wěn)妥起見用 -O2秦躯,這也是大多數(shù)軟件編譯推薦的優(yōu)化級(jí)別。查看Nginx源碼文件 auto/cc/gcc裆装,搜索NGX_GCC_OPT踱承,默認(rèn)GCC編譯參數(shù)為-O,可以直接修改內(nèi)容為NGX_GCC_OPT="-O2"或者在 ./configure配置時(shí)添加--with-cc-opt='-O2'選項(xiàng)哨免。
-g 調(diào)試
如果想用調(diào)試器執(zhí)行一個(gè)可執(zhí)行文件茎活, 在用gcc編譯時(shí)必須加上-g選項(xiàng):
gcc -o sum sum.c -g
加上-g選項(xiàng)以后,gcc在編譯是會(huì)做以下額外的操作:
- 創(chuàng)建符號(hào)表琢唾,符號(hào)表包含了程序中使用的變量名稱的列表载荔。
- 關(guān)閉所有的優(yōu)化機(jī)制,以便程序執(zhí)行過程中嚴(yán)格按照原來的C代碼進(jìn)行采桃。