c-cpp-compilers

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

C/C++ Compilers

C/C++ 编译器

Guidance for compiling, analyzing, and optimizing C and C++ code with GCC and Clang in 2026.
2026年使用GCC和Clang编译、分析及优化C和C++代码的指南。

Reference files

参考文档

  • GCC specifics: gcc.md -- flags, diagnostics, PGO, LTO, error triage
  • Clang specifics: clang.md -- diagnostics, optimization remarks, clang-tidy, macOS
  • Sanitizers: sanitizers.md -- ASan, UBSan, TSan, MSan, LSan decision tree and reports
  • Static analysis: static-analysis.md -- clang-tidy, cppcheck, scan-build, CI integration
  • Modern C/C++: modern-cpp.md -- C++20 modules, C++23/26 features, C23, migration
  • GCC 专属内容gcc.md -- 标志、诊断信息、PGO、LTO、错误排查
  • Clang 专属内容clang.md -- 诊断信息、优化备注、clang-tidy、macOS 适配
  • Sanitizersanitizers.md -- ASan、UBSan、TSan、MSan、LSan 决策树及报告解读
  • 静态分析static-analysis.md -- clang-tidy、cppcheck、scan-build、CI 集成
  • 现代C/C++modern-cpp.md -- C++20 模块、C++23/26 特性、C23、版本迁移

Standards baseline (2026)

标准基线(2026)

LanguagePreferred standardGCC supportClang support
C
-std=c23
(or
-std=c17
for broad compat)
GCC 15+Clang 18+
C++
-std=c++23
(or
-std=c++20
minimum)
GCC 14+Clang 18+
Always pass the standard flag explicitly. Never rely on compiler defaults.
语言推荐标准GCC支持版本Clang支持版本
C
-std=c23
(兼容广泛场景使用
-std=c17
GCC 15+Clang 18+
C++
-std=c++23
(最低要求
-std=c++20
GCC 14+Clang 18+
始终显式传递标准标志,切勿依赖编译器默认值。

Build modes

构建模式

GoalFlags
Debug
-g -O0 -Wall -Wextra -Wpedantic
Debug (GDB-friendly optimized)
-g -Og -Wall -Wextra
Release
-O2 -DNDEBUG -Wall
Release (max throughput, native)
-O3 -march=native -DNDEBUG -flto
Release (min binary size)
-Os -DNDEBUG
(Clang:
-Oz
)
Sanitizer build
-g -O1 -fsanitize=address,undefined -fno-omit-frame-pointer
目标标志
调试
-g -O0 -Wall -Wextra -Wpedantic
调试(GDB友好的优化版本)
-g -Og -Wall -Wextra
发布
-O2 -DNDEBUG -Wall
发布(最大吞吐量,原生适配)
-O3 -march=native -DNDEBUG -flto
发布(最小二进制体积)
-Os -DNDEBUG
(Clang:
-Oz
Sanitizer 构建
-g -O1 -fsanitize=address,undefined -fno-omit-frame-pointer

Warning discipline

警告规范

Start with
-Wall -Wextra -Wpedantic
. Add
-Werror
in CI.
Suppress narrow scopes only:
c
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
void callback(int ctx, int unused) { (void)ctx; }
#pragma GCC diagnostic pop
Clang equivalent works the same. For project-wide suppression, prefer
.clang-tidy
config or
-Wno-<flag>
in build system, not in source.
-Wall -Wextra -Wpedantic
开始,在CI环境中添加
-Werror
仅在窄范围内抑制警告:
c
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
void callback(int ctx, int unused) { (void)ctx; }
#pragma GCC diagnostic pop
Clang 等效语法作用相同。如需项目级别的警告抑制,优先使用
.clang-tidy
配置或构建系统中的
-Wno-<flag>
,而非在源码中处理。

Optimization decision tree

优化决策树

Need max throughput on known hardware?
  yes -> -O3 -march=native -flto
  no  -> Have profiling data?
           yes -> -O2 -fprofile-use (GCC) / -fprofile-instr-use (Clang)
           no  -> -O2

Size-constrained (embedded, shared lib)?
  yes -> -Os (GCC/Clang) or -Oz (Clang only)

Numerical code that tolerates IEEE relaxation?
  yes -> -Ofast (enables -ffast-math; breaks NaN/inf handling)
  no  -> stay with -O2/-O3
-O3
vs
-O2
:
-O3
adds aggressive loop transforms and wider inlining. Benchmark before committing -- i-cache pressure can cause regressions.
是否需要在已知硬件上达到最大吞吐量?
  是 -> -O3 -march=native -flto
  否 -> 是否有性能分析数据?
           是 -> -O2 -fprofile-use (GCC) / -fprofile-instr-use (Clang)
           否 -> -O2

是否受体积限制(嵌入式、共享库)?
  是 -> -Os (GCC/Clang) 或 -Oz (仅Clang)

数值计算代码是否允许放宽IEEE标准?
  是 -> -Ofast(启用-ffast-math;会破坏NaN/inf处理)
  否 -> 保持使用-O2/-O3
-O3
vs
-O2
-O3
增加了激进的循环转换和更广泛的内联。在提交前务必进行基准测试——指令缓存压力可能导致性能退化。

LTO

LTO

bash
undefined
bash
undefined

GCC

GCC

gcc -O2 -flto=auto -c foo.c bar.c gcc -O2 -flto=auto foo.o bar.o -o prog
gcc -O2 -flto=auto -c foo.c bar.c gcc -O2 -flto=auto foo.o bar.o -o prog

Clang (ThinLTO preferred for large projects)

Clang(大型项目优先使用ThinLTO)

clang -O2 -flto=thin -fuse-ld=lld -c foo.c bar.c clang -O2 -flto=thin -fuse-ld=lld foo.o bar.o -o prog

Use `gcc-ar` / `gcc-ranlib` for GCC LTO archives. Clang ThinLTO links 5-10x faster than full LTO with comparable code quality.
clang -O2 -flto=thin -fuse-ld=lld -c foo.c bar.c clang -O2 -flto=thin -fuse-ld=lld foo.o bar.o -o prog

GCC LTO 归档需使用 `gcc-ar` / `gcc-ranlib`。Clang ThinLTO 的链接速度比全量LTO快5-10倍,且代码质量相当。

PGO (profile-guided optimization)

PGO(基于性能分析的优化)

GCC:
bash
gcc -O2 -fprofile-generate prog.c -o prog_inst
./prog_inst < workload.input
gcc -O2 -fprofile-use -fprofile-correction prog.c -o prog
Clang (LLVM instrumentation):
bash
clang -O2 -fprofile-instr-generate prog.c -o prog_inst
./prog_inst < workload.input
llvm-profdata merge -output=prog.profdata default.profraw
clang -O2 -fprofile-instr-use=prog.profdata prog.c -o prog
GCC:
bash
gcc -O2 -fprofile-generate prog.c -o prog_inst
./prog_inst < workload.input
gcc -O2 -fprofile-use -fprofile-correction prog.c -o prog
Clang(LLVM 插桩):
bash
clang -O2 -fprofile-instr-generate prog.c -o prog_inst
./prog_inst < workload.input
llvm-profdata merge -output=prog.profdata default.profraw
clang -O2 -fprofile-instr-use=prog.profdata prog.c -o prog

Sanitizer quick reference

Sanitizer 速查

Bug classSanitizerFlag
Heap/stack/global OOB, use-after-free, double-freeASan
-fsanitize=address
Signed overflow, null deref, bad shift, misaligned accessUBSan
-fsanitize=undefined
Data racesTSan
-fsanitize=thread
Uninitialised reads (Clang only, all-instrumented build)MSan
-fsanitize=memory
Memory leaksLSanvia ASan (
detect_leaks=1
) or standalone
Common combo:
-fsanitize=address,undefined -fno-sanitize-recover=all -fno-omit-frame-pointer -g -O1
TSan and MSan are mutually exclusive with ASan. See sanitizers.md for report interpretation.
缺陷类型Sanitizer标志
堆/栈/全局内存越界、释放后使用、重复释放ASan
-fsanitize=address
有符号溢出、空指针解引用、非法移位、未对齐访问UBSan
-fsanitize=undefined
数据竞争TSan
-fsanitize=thread
未初始化读取(仅Clang支持,需全插桩构建)MSan
-fsanitize=memory
内存泄漏LSan通过ASan启用(
detect_leaks=1
)或独立使用
常用组合:
-fsanitize=address,undefined -fno-sanitize-recover=all -fno-omit-frame-pointer -g -O1
TSan 和 MSan 与 ASan 互斥。报告解读请参考 sanitizers.md

Static analysis (quick start)

静态分析(快速入门)

bash
undefined
bash
undefined

Generate compilation database

生成编译数据库

cmake -S . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
cmake -S . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON

Run clang-tidy (recommended checks)

运行clang-tidy(推荐检查项)

clang-tidy -checks='bugprone-,clang-analyzer-,performance-,modernize-'
-p build src/foo.cpp
clang-tidy -checks='bugprone-,clang-analyzer-,performance-,modernize-'
-p build src/foo.cpp

Run cppcheck

运行cppcheck

cppcheck --enable=warning,performance,portability --error-exitcode=1 src/

See [static-analysis.md](reference/static-analysis.md) for `.clang-tidy` config, CI integration, and suppression patterns.
cppcheck --enable=warning,performance,portability --error-exitcode=1 src/

`.clang-tidy` 配置、CI集成及警告抑制模式请参考 [static-analysis.md](reference/static-analysis.md)。

Common error triage

常见错误排查

SymptomLikely causeFix
undefined reference to 'foo'
Missing
-lfoo
or wrong link order
Libraries after objects:
gcc main.o -lfoo
multiple definition of 'x'
Defined in header without
static
/
inline
extern
in header, define in one
.c
implicit declaration of function
Missing
#include
or wrong standard
Add the header; check
-std=
incompatible pointer types
Wrong cast or missing prototypeFix type; enable
-Wall
ABI errors in C++Mixed
-std=
or different
libstdc++
Unify standard across all TUs
relocation truncated
32-bit relocation overflow
-mcmodel=large
or restructure
症状可能原因修复方案
undefined reference to 'foo'
缺少
-lfoo
或链接顺序错误
库放在目标文件之后:
gcc main.o -lfoo
multiple definition of 'x'
在头文件中定义变量但未加
static
/
inline
头文件中用
extern
声明,在单个
.c
文件中定义
implicit declaration of function
缺少
#include
或标准版本错误
添加对应头文件;检查
-std=
标志
incompatible pointer types
类型转换错误或缺少函数原型修正类型;启用
-Wall
C++ 中的ABI错误混合使用不同
-std=
标准或
libstdc++
版本
统一所有编译单元的标准版本
relocation truncated
32位重定位溢出使用
-mcmodel=large
或重构代码

CMake integration

CMake 集成

cmake
cmake_minimum_required(VERSION 3.28)
project(myproject LANGUAGES C CXX)

set(CMAKE_C_STANDARD 23)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

option(SANITIZE "Build with ASan+UBSan" OFF)
if(SANITIZE)
    set(san_flags -fsanitize=address,undefined -fno-sanitize-recover=all
                  -fno-omit-frame-pointer -g -O1)
    add_compile_options(${san_flags})
    add_link_options(${san_flags})
endif()
cmake
cmake_minimum_required(VERSION 3.28)
project(myproject LANGUAGES C CXX)

set(CMAKE_C_STANDARD 23)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

option(SANITIZE "Build with ASan+UBSan" OFF)
if(SANITIZE)
    set(san_flags -fsanitize=address,undefined -fno-sanitize-recover=all
                  -fno-omit-frame-pointer -g -O1)
    add_compile_options(${san_flags})
    add_link_options(${san_flags})
endif()

Useful one-liners

实用单行命令

bash
undefined
bash
undefined

Show all optimizations enabled at -O2 (GCC)

查看-O2级别下启用的所有优化项(GCC)

gcc -Q --help=optimizers -O2 | grep enabled
gcc -Q --help=optimizers -O2 | grep enabled

Assembly output (Intel syntax)

生成汇编代码(Intel语法)

gcc -S -masm=intel -O2 foo.c -o foo.s
gcc -S -masm=intel -O2 foo.c -o foo.s

Preprocess and dump macros

预处理并导出宏定义

gcc -dM -E - < /dev/null
gcc -dM -E - < /dev/null

Clang optimization remarks (missed vectorization)

Clang 优化备注(未完成向量化)

clang -O2 -Rpass-missed=loop-vectorize src.c
clang -O2 -Rpass-missed=loop-vectorize src.c

Clang save all remarks to YAML

Clang 将所有优化备注保存为YAML

clang -O2 -fsave-optimization-record src.c
clang -O2 -fsave-optimization-record src.c

Show include search path

查看头文件搜索路径

gcc -v -E - < /dev/null 2>&1 | grep -A20 '#include <...>'
undefined
gcc -v -E - < /dev/null 2>&1 | grep -A20 '#include <...>'
undefined

Compiler-specific details

编译器专属细节

For GCC-specific flags, PGO nuances, and error patterns, see gcc.md. For Clang diagnostics, optimization remarks, macOS toolchain, and clang-tidy, see clang.md. For C++20 modules, C++23/26, and C23 features, see modern-cpp.md.
GCC专属标志、PGO细节及错误模式请参考 gcc.md。 Clang诊断信息、优化备注、macOS工具链及clang-tidy相关内容请参考 clang.md。 C++20模块、C++23/26及C23特性相关内容请参考 modern-cpp.md