以下大略整理一下此次更新的部份, 主要整理自官方 Release 頁面[1], 但由於個人偏好, 非ARM, C/C++ 將不會出現在下面:
一般性
- GCC 切換使用 C++ 實作, 回不去了, 但要注意 GCC 中目前政策是只使用 C++2003 的 subset, 禁止列表可參考 [3]
- GCC 現在採用更激烈(aggressive)註2的最佳化, 同時也增加 -fno-aggressive-loop-optimizations 這個選項來避免過激行為
- DWARF4 為預設產生的 Debug Info
- 新的選項 -Og 可以產生有最佳化但又方便 Debug 的 Code, 以後可以不用下 -O0 -g3 可以換下 -Og -g3 了
- 新的最佳化選項 -ftree-partial-pre , 預設開啟於 -O3
- Struct 及 Matrix 的 reorg 功能被拔掉了(-fipa-struct-reorg 及 -fipa-matrix-reorg), 因為有機率產生出爛掉的東西, 而且 lto 時會爛掉
- LTO 大幅改善
- AddressSanitizer 及 ThreadSanitize 正式加入, 分別使用 -fsanitize=address 及 -fsanitize=thread 來開啟, AddressSanitizer 功能簡介可參照[5]
語言相關
- 錯誤訊息會用 ^ 來標示出錯誤地點, 例如以下是少分號的範例
#include<stdio.h> #include<stdlib.h> int main(){ return 0 }
GCC 4.8 的錯誤訊息test.c: In function ‘main’: test.c:6:1: error: expected ‘;’ before ‘}’ token } ^
但跟 clang 比起來似乎還是沒做的很好, clang 的輸出範例:test.c:5:11: error: expected ';' after return statement return 0 ^ ;
更多比較可參考[6] - 新的選項 -ftrack-macro-expansion=
可以在讓你在顯示錯誤訊息時展開 Marco N 層, 範例: #define MARCO_(a, b) a b #define MARCO(a, b) MARCO_(a, b) void f(int a, int b) { MARCO(a, b); }
GCC 4.7.2 的錯誤訊息marco.c: In function ‘f’: marco.c:5:3: error: expected ‘;’ before ‘b’
GCC 4.8 的錯誤訊息marco.c: In function ‘f’: marco.c:6:12: error: expected ‘;’ before ‘b’ MARCO(a, b); ^ marco.c:2:24: note: in definition of macro 'MARCO_' #define MARCO_(a, b) a b ^ marco.c:6:3: note: in expansion of macro 'MARCO' MARCO(a, b); ^
clang 的錯誤訊息marco.c:6:12: error: expected ';' after expression MARCO(a, b); ^ marco.c:3:31: note: expanded from macro 'MARCO' #define MARCO(a, b) MARCO_(a, b) ^ marco.c:2:24: note: expanded from macro 'MARCO_' #define MARCO_(a, b) a b ^
- 新的警告 -Wsizeof-pointer-memaccess, 當該填 size 時你直接 sizeof(pointer) 就會跟你抱怨, 範例如下:
#include <string.h> void f(int *p){ memset(p, 1, sizeof(p)); }
然後開 -Wall 或 -Wsizeof-pointer-memaccess 會跟你抱怨memset.c: In function ‘f’: memset.c:4:22: warning: argument to ‘sizeof’ in ‘memset’ call is the same expression as the destination; did you mean to dereference it? [-Wsizeof-pointer-memaccess] memset(p, 1, sizeof(p)); ^
不過還是要說一下 clang 吐出來的資訊比較清楚memset.c:4:23: warning: 'memset' call operates on objects of type 'int' while the size is based on a different type 'int *' [-Wsizeof-pointer-memaccess] memset(p, 1, sizeof(p)); ~ ^ memset.c:4:23: note: did you mean to dereference the argument to 'sizeof' (and multiply it by the number of elements)? memset(p, 1, sizeof(p)); ^
C++11專區
- thread_local 關鍵字實作了!
- 的 attribute 及 alignment 實作, 範例:
[[noreturn]] void f(); alignas(double) int i;
ARM
- AArch 64 支援
- ARM 的 AAPCS ABI 有稍微更動, 有關 vector types 部份的 ABI 將無法與舊的 GCC 產生的 Code 相容
- 現在 GCC 會想辦法產生 VFMA, VFMS, REVSH 及 REV16 指令
- 新的 Inst Scheduler 會考慮 Register Pressure, 不喜歡的話可透過 -fno-sched-pressure 關掉
- 支援 Marvell 的 iWMMX2 SIMD, 可透過指定 -mcpu=iwmmxt2 來開啟
註2: Aggressive 這個字眼在 Compiler 領域中通常代表需要花較多時間分析及最佳化, 並且也有可能不會比較好(指 Code Size 或 Performance)
Reference
[1] GCC 4.8 Release 官方網頁[2] C++ Conversion(GCC Wiki)
[3] http://gcc.gnu.org/wiki/CppConventions
[4] GCC and C vs C++ Speed, Measured
[5] Address-sanitizer : 新的 Android 快速記憶體錯誤偵測工具
[6] C++ Diagnostic Survey