使用技巧
常用选项
1.基本编译选项
-
-o <output_file>
指定输出文件名(可执行文件或目标文件)。g++ -o my_program main.cpp → 生成名为 my_program 的可执行文件
-
-c
只编译源代码为目标文件(不链接)。g++ -c main.cpp → 生成 main.o
-
-S
生成汇编代码文件(.s)。g++ -S main.cpp → 生成 main.s
-
-E
只运行预处理,不进行编译,输出预处理结果。g++ -E main.cpp → 输出预处理后的代码
2.标准选择
- -std=c++11
指定使用 C++ 标准(如 c++98、c++11、c++14、c++20)。g++ -std=c++17 main.cpp
- -pedantic
启用严格的 ISO C++ 标准兼容性检查。
3.调试
- -g
启用调试信息(生成符号表,可用于调试器如 gdb)。g++ -g -o my_program main.cpp
4.优化
- -O0
不进行优化(默认)。g++ -O0 -o hello_O0 main.cpp ./hello_O0
- -O1
启用基本优化。 - -O2
启用更高的优化级别,注重性能与代码大小的平衡。 - -O3
最大优化,可能导致更长的编译时间。 - -Ofast
极端优化,不完全遵循标准。
5.警告与错误处理
-
-Wall
启用大部分常见警告。 -
-Wextra
启用额外的警告。g++ -Wall -Wextra -o hello_warning main.cpp # 检查是否有警告
-
-Werror
将所有警告视为错误(强制修复警告)。 -
-Wshadow
警告变量名遮蔽问题(如局部变量遮蔽全局变量)。g++ -Wall -Wextra -o my_program main.cpp
6.链接与库
- -l (library)
链接指定库(注意:库名不带 lib 前缀和 .so 或 .a 后缀)。g++ -o my_program main.cpp -lm → 链接数学库 libm.so
- -L (path)
指定库搜索路径。g++ -L/usr/local/lib -o my_program main.cpp -lmylib
7.多线程与并行编译
- -pthread
启用 POSIX 线程支持(必要时添加)。g++ -pthread main.cpp
- -j (n)
启用并行编译(用于 make 时)。n 是线程数。
MakeFile
MakeFile:记录一个项目编译流程及规则,找到makefile所在文件夹,命令行输入make,即可编译。
# 变量定义
CXX = g++
CXXFLAGS = -std=c++11 -Wall -O2 -g
LDFLAGS = -pthread
# 可执行文件目标
TARGET = helloworld
# 源文件和目标文件
SRC = helloworld.cpp
OBJ = helloworld.o
# 默认目标
all: $(TARGET)
# 生成目标文件
$(TARGET): $(OBJ)
$(CXX) $(LDFLAGS) -o $(TARGET) $(OBJ)
# 编译 .cpp 文件为 .o 文件
$(OBJ): $(SRC)
$(CXX) $(CXXFLAGS) -c $(SRC)
# 清理生成的文件
clean:
rm -f $(TARGET) $(OBJ)
# 安装
install: $(TARGET)
# 安装命令,如复制到指定目录
cp $(TARGET) /usr/local/bin
.PHONY: all clean install
- $^ :所有依赖对象。
- $<:表示历来对象的第一个。
- $@:表示目标对象。
GDB 调试
# gcc -g helloworld.c -o helloworld
以helloworld为例,解释调试命令。
# gdb ./helloworld //启动gdb调试
- 程序运行
命令/缩写 | 作用 | 示例 |
---|---|---|
run(r) | 运行程序。 | (gdb) run arg1 |
start | 逐步调试。 | - |
- 调试控制
命令/缩写 | 作用 |
---|---|
step(s) | 逐行执行程序,每执行一条指令就暂停。 |
next(n) | 单步调试,不进入函数:这会逐行执行,但遇到函数调用时不会进入函数体内。 |
continue(c) | 让程序继续执行,直到下一个断点或程序结束。 |
quit(q) | 退出GDB。 |
- 断点,查看信息
命令/缩写 | 作用 | 示例 |
---|---|---|
backtrace(bt) | 查看函数调用栈,快速定位程序崩溃位置。 | |
break(b) | 设置断点。 | 1. 按行打断点 => (gdb) break 10 2.按照函数名设置断点 => (gdb) break function 3.指定文件和行号 => (gdb) break hello.cpp:10 4.使用条件断点 => (gdb) break function if x>10 5. 按内存地址设置断点 => (gdb) break *0x87043a0 |
watch | 查看变量值及变化。 | 根据变量名称查看变量值变化 => (gdb) watch x |
info | 显示各种信息,如寄存器状态、断点列表。 | 查看所有断点信息 => (gdb) info breakpoints |
enable | 启用断点。 | 根据断点id,启用断点 => (gdb) enable 2 |
disable | 禁用断点。 | 根据断电id,禁用断点 => (gdb) disable 2 |
delete | 删除断点。 | 根据断点id,删除断点 => (gdb) delete 2 |
print(p) | 打印变量值。 | 根据变量名称,打印变量的值 => print x |
- 其他
命令/缩写 | 作用 | 示例 |
---|---|---|
set | 修改变量的值。 | (gdb) set x = 10 |
display | 跟踪查看一个变量,每次停下显示变量的值。 | (gdb) display x |
undisplay | 取消跟踪。 | (gdb) undisplay x |
until | 运行跳至指定行。 | (gdb) until 10 |
x/10xw 0xaddress | 查看内存的内容。从0xaddress开始查看10个字的内容。 | – |
多进程调试
父进程(默认):set follow-fork-mode <parent>
子进程:set follow-fork-mode child
设置调试模式:set detach-on-fork <on/off>
- on:其他进程继续执行。
- off:其他进程挂起。
查看调试的进程:info inferios
切换调试的进程:inferior process_id
多线程调试
查看进程:ps aux|grep process_name
查看线程:ps -aL|grep process_name
查看进程树:pstree -p main_thread_id
调试
- 查看线程:
info threads
- 切换线程:
thread thread_id
只运行当前线程:set scheduler-locking on
运行全部线程:set scheduler-locking off
指定某个线程执行gdb命令:thread apply thread_id cmd
全部线程执行某个命令:thread apply all cmd