(1)c/c++編譯過程
編譯一個.cpp文件時, 經過處理、編譯、匯編和鏈接 4 個步驟,生成一個可執行程序:

gcc編譯過程
1. 預處理:將(include)的文件插入原文件中、將宏定義展開、根據條件編譯命令選擇要使用的代碼
2. 編譯: 將預處理得到的源代碼文件,進行“翻譯轉換”, 生成匯編代碼(編譯階段要檢查代碼的規范性、是否有語法錯誤,如函數、變量是否被聲明等)
3. 匯編: 將匯編代碼翻譯成了機器碼,表現為二進制文件
4. 鏈接: 將匯編生成的.o文件及其他函數庫文件鏈接起來,生成能在特定平台上運行的可執行程序(在鏈接程序時,鏈接器會在所有的目標文件中找尋函數的實現。如果找不到,那到就會報鏈接錯誤碼(LinkerError))
(2)gcc編譯選項
1. 常用命令選項
1 --version 查看gcc版本號 2 -std 指定C或C++語言標准版本。比如 -std=c89,-std=c99等是C語言的標准版本號。-std=c++11,-std=c++14等就是C++語言的標准版本號 3 -o 指定輸出文件,如果沒有-o,輸出有可能直接到stdout,有可能到默認的a.out文件 4 -E 只做pre-process,預編譯,要使用-o指定輸出文件,此時文件一般都用.i結尾 5 -S(大寫) 編譯到(assembly)匯編,使用-o指定輸出文件,此時文件一般都用.s結尾; 6 -c 只編譯,不鏈接,用-o指定輸出文件,此時文件一般用.o結尾 7 -g 附加debug信息,在輸出的.o和可執行文件中,有很多.debug段。(compile for debugging) 8 -static 用靜態鏈接的方式編譯,默認是動態鏈接,靜態鏈接生產的文件體積會很大 9 -shared 生成.so動態鏈接庫 10 -fPIC 一般在創建.so動態鏈接庫的時候,都要加上-fPIC參數。 11 -fPIC 作用於編譯階段,告訴編譯器產生與位置無關代碼(Position-Independent Code),則產生的代碼中,沒有絕對地址,全 12 部使用相對地址,故而代碼可以被加載器加載到內存的任意位置,都可以正確的執行。這正是共享庫所要求的,共享庫被加載時,在內存的位置不是固定的 13 -O0 14 -O1 15 -O2 16 -O3 編譯器的優化選項的4個級別,-O0表示沒有優化,-O1為缺省值,-O3優化級別最高 17 -Wall 顯示大部分編譯告警,強烈建議使用。(不是全部哦) 18 19 -Wextra 打印一些額外的告警信息,一般會與-Wall一起使用。 20 21 -W 可以用來打開或者關閉某個告警,比如顯示這個告警 -Wsequence-point,要關閉它就寫 -Wno-sequence-point。 22 23 -w 關閉所有告警信息 24 25 -Werror 有warning時也當成error來處理,此時編譯會終止。 26 27 就是這個選項導致的這這樣的錯誤顯示:cc1plus: all warnings being treated as errors。快速地解決方法就是去掉-Werror,可能需要修改makefile。 28 29 -D 添加宏定義,不用修改代碼,就可以控制條件編譯開關。 30 31 比如:-DMARCO,效果相當於 #define MARCO 1 32 33 比如:-DMARCO=ABCDE,效果相當於 #define MARCO ABCDE 34 35 -UMARCO 取消宏MARCO的定義 36 37 -I 提供額外頭文件搜索路徑,-Idir 38 39 -L(大寫) 提供額外的函數庫搜索路徑,-Ldir 40 41 -l(小寫) 庫鏈接時搜索指定的函數庫,-lLIB 42 43 -M 生成文件關聯的信息。包含目標文件所依賴的所有源代碼 44 45 -MM 和上面的那個一樣,但是它將忽略由#include<file>造成的依賴關系 46 47 -MD 和-M相同,但是輸出將導入到.d的文件里面 48 49 -MMD 和-MM相同,但是輸出將導入到.d的文件里面 50 51 -lstdc++ 編譯c++代碼(相當於g++)
2. 警告信息控制選項
1 --all-warnings 此開關缺少可用文檔 2 --extra-warnings 此開關缺少可用文檔 3 -W 不建議使用此開關;請改用 -Wextra 4 -Wabi 當結果與 ABI 5 相容的編譯器的編譯結果不同時給出警告 6 -Waddress 使用可疑的內存地址時給出警告 7 -Waggregate-return 當返回結構、聯合或數組時給出警告 8 -Waliasing 為可能的虛參重疊給出警告 9 -Walign-commons 對 COMMON 塊對齊的警告 10 -Wall 啟用大部分警告信息 11 -Wampersand 若延續字符常量中缺少 & 則給出警告 12 -Warray-bounds 當數組訪問越界時給出警告 13 -Warray-temporaries 創建臨時數組時給出警告 14 -Wassign-intercept 當 Objective-C 15 賦值可能為垃圾回收所介入時給出警告 16 -Wattributes 當對屬性的使用不合適時給出警告 17 -Wbad-function-cast 當把函數轉換為不兼容類型時給出警告 18 -Wbuiltin-macro-redefined 當內建預處理宏未定義或重定義時給出警告 19 -Wc++-compat 當在 C 語言中使用了 C 與 C++ 20 交集以外的構造時給出警告 21 -Wc++0x-compat 當 C++ 構造的意義在 ISO C++ 1998 和 ISO 22 C++ 200x 中不同時給出警告 23 -Wcast-align 當轉換指針類型導致對齊邊界增長時給出警告 24 -Wcast-qual 當類型轉換丟失限定信息時給出警告 25 -Wchar-subscripts 當下標類型為“char”時給出警告 26 -Wcharacter-truncation 對被截斷的字符表達式給出警告 27 -Wclobbered 對能為"longjmp"或"vfork"所篡改的變量給出警告 28 -Wcomment 對可能嵌套的注釋和長度超過一個物理行長的 29 C++ 注釋給出警告 30 -Wcomments -Wcomment 的同義詞 31 -Wconversion 當隱式類型轉換可能改變值時給出警告 32 -Wconversion-extra 對大多數隱式類型轉換給出警告 33 -Wconversion-null 將 NULL 轉換為非指針類型時給出警告 34 -Wcoverage-mismatch Warn in case profiles in -fprofile-use do not 35 match 36 -Wcpp Warn when a #warning directive is encountered 37 -Wctor-dtor-privacy 當所有構造函數和析構函數都是私有時給出警告 38 -Wdeclaration-after-statement 當聲明出現在語句后時給出警告 39 -Wdeprecated 使用不建議的編譯器特性、類、方法或字段時給出警告 40 -Wdeprecated-declarations 對 __attribute__((deprecated)) 聲明給出警告 41 -Wdisabled-optimization 當某趟優化被禁用時給出警告 42 -Wdiv-by-zero 對編譯時發現的零除給出警告 43 -Wdouble-promotion 對從“float”到“double”的隱式轉換給出警告 44 -Weffc++ 對不遵循《Effetive 45 C++》的風格給出警告 46 -Wempty-body 當 if 或 else 語句體為空時給出警告 47 -Wendif-labels 當 #elif 和 #endif 48 后面跟有其他標識符時給出警告 49 -Wenum-compare 對不同枚舉類型之間的比較給出警告 50 -Werror 不建議使用此開關;請改用 51 -Werror=implicit-function-declaration 52 -Wextra 打印額外(可能您並不想要)的警告信息 53 -Wfloat-equal 當比較浮點數是否相等時給出警告 54 -Wformat 對 printf/scanf/strftime/strfmon 55 中的格式字符串異常給出警告 56 -Wformat-contains-nul 當格式字符串包含 NUL 字節時給出警告 57 -Wformat-extra-args 當傳遞給格式字符串的參數太多時給出警告 58 -Wformat-nonliteral 當格式字符串不是字面值時給出警告 59 -Wformat-security 當使用格式字符串的函數可能導致安全問題時給出警告 60 -Wformat-y2k 當 strftime 格式給出 2 61 位記年時給出警告 62 -Wformat-zero-length 對長度為 0 的格式字符串給出警告 63 -Wformat= 此開關缺少可用文檔 64 -Wignored-qualifiers 當類型限定符被忽略時給出警告。 65 -Wimplicit 對隱式函數聲明給出警告 66 -Wimplicit-function-declaration 對隱式函數聲明給出警告 67 -Wimplicit-int 當聲明未指定類型時給出警告 68 -Wimplicit-interface 對帶有隱式接口的調用給出警告 69 -Wimplicit-procedure 對沒有隱式聲明的過程調用給出警告 70 -Winit-self 對初始化為自身的變量給出警告。 71 -Winline 當內聯函數無法被內聯時給出警告 72 -Wint-to-pointer-cast 當將一個大小不同的整數轉換為指針時給出警告 73 -Wintrinsic-shadow 如果用戶過程有與內建過程相同的名字則警告 74 -Wintrinsics-std 當內建函數不是所選標准的一部分時給出警告 75 -Winvalid-offsetof 對“offsetof”宏無效的使用給出警告 76 -Winvalid-pch 在找到了 PCH 77 文件但未使用的情況給出警告 78 -Wjump-misses-init 當跳轉略過變量初始化時給出警告 79 -Wlarger-than- 此開關缺少可用文檔 80 -Wlarger-than=<N> 當目標文件大於 N 字節時給出警告 81 -Wline-truncation 對被截斷的源文件行給出警告 82 -Wlogical-op 當邏輯操作結果似乎總為真或假時給出警告 83 -Wlong-long 當使用 -pedantic 時不對“long 84 long”給出警告 85 -Wmain 對可疑的“main”聲明給出警告 86 -Wmissing-braces 若初始值設定項中可能缺少花括號則給出警告 87 -Wmissing-declarations 當全局函數沒有前向聲明時給出警告 88 -Wmissing-field-initializers 若結構初始值設定項中缺少字段則給出警告 89 -Wmissing-format-attribute 當函數可能是 format 90 屬性的備選時給出警告 91 -Wmissing-include-dirs 當用戶給定的包含目錄不存在時給出警告 92 -Wmissing-noreturn 當函數可能是 __attribute__((noreturn)) 93 的備選時給出警告 94 -Wmissing-parameter-type K&R 95 風格函數參數聲明中未指定類型限定符時給出警告 96 -Wmissing-prototypes 全局函數沒有原型時給出警告 97 -Wmudflap 當構造未被 -fmudflap 處理時給出警告 98 -Wmultichar 使用多字節字符集的字符常量時給出警告 99 -Wnested-externs 當“extern”聲明不在文件作用域時給出警告 100 -Wnoexcept Warn when a noexcept expression evaluates to 101 false even though the expression can't actually 102 throw 103 -Wnon-template-friend 在模板內聲明未模板化的友元函數時給出警告 104 -Wnon-virtual-dtor 當析構函數不是虛函數時給出警告 105 -Wnonnull 當將 NULL 傳遞給需要非 NULL 106 的參數的函數時給出警告 107 -Wnormalized=<id|nfc|nfkc> 對未歸一化的 Unicode 字符串給出警告 108 -Wold-style-cast 程序使用 C 109 風格的類型轉換時給出警告 110 -Wold-style-declaration 對聲明中的過時用法給出警告 111 -Wold-style-definition 使用舊式形參定義時給出警告 112 -Woverflow 算術表示式溢出時給出警告 113 -Woverlength-strings 當字符串長度超過標准規定的可移植的最大長度時給出警告 114 -Woverloaded-virtual 重載虛函數名時給出警告 115 -Woverride-init 覆蓋無副作用的初始值設定時給出警告 116 -Wpacked 當 packed 117 屬性對結構布局不起作用時給出警告 118 -Wpacked-bitfield-compat 當緊實位段的偏移量因 GCC 4.4 119 而改變時給出警告 120 -Wpadded 當需要填補才能對齊結構成員時給出警告 121 -Wparentheses 可能缺少括號的情況下給出警告 122 -Wpmf-conversions 當改變成員函數指針的類型時給出警告 123 -Wpointer-arith 當在算術表達式中使用函數指針時給出警告 124 -Wpointer-sign 賦值時如指針符號不一致則給出警告 125 -Wpointer-to-int-cast 將一個指針轉換為大小不同的整數時給出警告 126 -Wpragmas 對錯誤使用的 pragma 加以警告 127 -Wproperty-assign-default Warn if a property for an Objective-C object has 128 no assign semantics specified 129 -Wprotocol 當繼承來的方法未被實現時給出警告 130 -Wreal-q-constant Warn about real-literal-constants with 'q' 131 exponent-letter 132 -Wredundant-decls 對同一個對象多次聲明時給出警告 133 -Wreorder 編譯器將代碼重新排序時給出警告 134 -Wreturn-type 當 C 135 函數的返回值默認為“int”,或者 C++ 136 函數的返回類型不一致時給出警告 137 -Wselector 當選擇子有多個方法時給出警告 138 -Wsequence-point 當可能違反定序點規則時給出警告 139 -Wshadow 當一個局部變量掩蓋了另一個局部變量時給出警告 140 -Wsign-compare 在有符號和無符號數間進行比較時給出警告 141 -Wsign-promo 當重載將無符號數提升為有符號數時給出警告 142 -Wstack-protector 當因為某種原因堆棧保護失效時給出警告 143 -Wstrict-aliasing 當代碼可能破壞強重疊規則時給出警告 144 -Wstrict-aliasing= 當代碼可能破壞強重疊規則時給出警告 145 -Wstrict-null-sentinel 將未作轉換的 NULL 146 用作哨兵時給出警告 147 -Wstrict-overflow 禁用假定有符號數溢出行為未被定義的優化 148 -Wstrict-overflow= 禁用假定有符號數溢出行為未被定義的優化 149 -Wstrict-prototypes 使用了非原型的函數聲明時給出警告 150 -Wstrict-selector-match 當備選方法的類型簽字不完全匹配時給出警告 151 -Wsuggest-attribute=const Warn about functions which might be candidates 152 for __attribute__((const)) 153 -Wsuggest-attribute=noreturn 當函數可能是 __attribute__((noreturn)) 154 的備選時給出警告 155 -Wsuggest-attribute=pure Warn about functions which might be candidates 156 for __attribute__((pure)) 157 -Wsurprising 對“可疑”的構造給出警告 158 -Wswitch 當使用枚舉類型作為開關變量,沒有提供 159 default 分支,但又缺少某個 case 160 時給出警告 161 -Wswitch-default 當使用枚舉類型作為開關變量,但沒有提供“default”分支時給出警告 162 -Wswitch-enum 當使用枚舉類型作為開關變量但又缺少某個 163 case 時給出警告 164 -Wsync-nand 當 __sync_fetch_and_nand 和 165 __sync_nand_and_fetch 166 內建函數被使用時給出警告 167 -Wsynth 不建議使用。此開關不起作用。 168 -Wsystem-headers 不抑制系統頭文件中的警告 169 -Wtabs 允許使用不符合規范的制表符 170 -Wtraditional 使用了傳統 C 171 不支持的特性時給出警告 172 -Wtraditional-conversion 原型導致的類型轉換與無原型時的類型轉換不同時給出警告 173 -Wtrampolines Warn whenever a trampoline is generated 174 -Wtrigraphs 當三字母序列可能影響程序意義時給出警告 175 -Wtype-limits 當由於數據類型范圍限制比較結果永遠為真或假時給出警告 176 -Wundeclared-selector 當使用 @selector() 177 卻不作事先聲明時給出警告 178 -Wundef 當 #if 179 指令中用到未定義的宏時給出警告 180 -Wunderflow 數字常量表達式下溢時警告 181 -Wuninitialized 自動變量未初始化時警告 182 -Wunknown-pragmas 對無法識別的 pragma 加以警告 183 -Wunsafe-loop-optimizations 當循環因為不平凡的假定而不能被優化時給出警告 184 -Wunsuffixed-float-constants 對不帶后綴的浮點常量給出警告 185 -Wunused 啟用所有關於“XX未使用”的警告 186 -Wunused-but-set-parameter Warn when a function parameter is only set, 187 otherwise unused 188 -Wunused-but-set-variable Warn when a variable is only set, otherwise unused 189 -Wunused-dummy-argument 對未使用的啞元給出警告。 190 -Wunused-function 有未使用的函數時警告 191 -Wunused-label 有未使用的標號時警告 192 -Wunused-macros 當定義在主文件中的宏未被使用時給出警告 193 -Wunused-parameter 發現未使用的函數指針時給出警告 194 -Wunused-result 當一個帶有 warn_unused_result 195 屬性的函數的調用者未使用前者的返回值時給出警告 196 -Wunused-value 當一個表達式的值未被使用時給出警告 197 -Wunused-variable 有未使用的變量時警告 198 -Wvariadic-macros 指定 -pedantic 199 時不為可變參數宏給出警告 200 -Wvla 使用變長數組時警告 201 -Wvolatile-register-var 當一個寄存器變量被聲明為 volatile 202 時給出警告 203 -Wwrite-strings 在 C++ 204 中,非零值表示將字面字符串轉換為‘char 205 *’時給出警告。在 C 206 中,給出相似的警告,但這種類型轉換是符合 207 ISO C 標准的。 208 -frequire-return-statement Functions which return values must end with 209 return statements
3. 編譯優化選項
1 -O1 最小化空間 minimize space
2 -Op[-] 改善浮點數一致性 improve floating-pt consistency 3 -O2 最大化速度 maximize speed 4 -Os 優選代碼空間 favor code space 5 -Oa 假設沒有別名 assume no aliasing 6 -Ot 優選代碼速度 favor code speed 7 -Ob 內聯展開(默認 n=0) inline expansion (default n=0) 8 -Ow 假設交叉函數別名 assume cross-function aliasing 9 -Od 禁用優化(默認值) disable optimizations (default) 10 -Ox 最大化選項。(-Ogityb2 -Gs) maximum opts. (-Ogityb1 -Gs) 11 -Og 啟用全局優化 enable global optimization 12 -Oy[-] 啟用框架指針省略 enable frame pointer omission 13 -Oi 啟用內建函數 enable intrinsic functions
