GCC 使用及技巧
本文仅介绍 GCC 的使用以及在 OI 中使用的技巧,不涉及任何工程项目!
介绍
GCC 不用多说,是指的 GNU 编写的 C C++ 编译器。包含 gcc、g++、gdb 等软件。
安装
大多数 C++ 的 IDE 都集成了 GCC(除了 Visual Studio 使用的 MSVC 和 Xcode 默认使用的是 Clang)(Visual Studio Code 和 Vim 等属于编辑器,不含有 GCC),若要安装 GCC 也很简单。
Windows 上可选择 MinGW-w64,macOS 可在安装 Homebrew
的基础上在终端输入 brew install gcc
安装。
Linux 上可使用 sudo apt-get install build-essentia
命令(对于 Debian 及其衍生发行版),对于其他发行版则使用
sudo pacman -S gcc g++
(使用 Arch Linux 举例)。
如果你是 Windows 10 或 Windows 11 用户,强烈推荐使用 WSL2 安装 Ubuntu,在 Ubuntu 中使用 GCC。这样可以避免本地与评测的环境差异。
安装成功后可用 gcc -v
或 g++ -v
检查安装。若安装成功应为下列输出:
1 | xenonwzh@XenonWZH-Surface:~$ gcc -v |
部分 IDE 与编辑器下 GCC 的设置
Dev-C++
Dev-C++ 可在菜单栏中选择 工具,编译选项。之后会弹出下列窗口。
在窗口中“编译时加入一下命令”打勾,可在里面输入 GCC 参数(不含
-o test
)。
Visual Studio Code
Code Runner
在 Visual Studio Code 设置中点击“打开设置(json)”,在该 json 文件最外层大括号末尾添加下列语句:
1 | "code-runner.executorMap": { |
即可在 "cpp"
对应的字符串中修改 g++
参数。
C / C++ 官方扩展
在 Visual Studio Code 中打开编写程序的文件夹,打开一个 C++
文件,在菜单栏中点击 终端、配置默认生成任务。之后在弹出的 json 文件中
修改 "args"
参数即可。
clangd
打开文件夹,在文件夹下新建 compile_flags.txt
文件,在该文件中添加 GCC 编译选项即可(同样不含
-o test
)
编译
下文将以 g++
举例,gcc
同理。
GCC 可编译单文件,语法如下:
1 | g++ test.cpp |
此时可生成一个文件 a.out
(Windows 下为
a.exe
)。
若想让生成的程序变成指定文件名,可使用下列语句:
1 | g++ test.cpp -o test |
此时会生成名为 test
的文件(Windows 下为
test.exe
)
若想使用新版本的特性,可使用下列指令(以 ISO C++ 14 为例)(目前的 NOI 系列比赛使用的 GCC 已默认开启 ISO C++ 14):
1 | g++ test.cpp -std=c++14 |
若想开启 O2 优化,可使用下列指令目前的 NOI 系列比赛使用的 GCC 未 默认开启 O2):
1 | g++ test.cpp -O2 |
若想使用 GDB 调试,则可以使用下列语句:
1 | g++ test.cpp -g |
以上如
-o
、-std=c++14
、-O2
、-g
以及下列将介绍的参数均可叠加使用。
与 OI 无关的知识点
众所周知宏观的编译操作分为编译、链接两大操作,GCC 也支持编译以及链接操作。
1 | g++ test.cpp -c # 编译,生成对象文件 test.o |
警告
GCC 编译会产生警告乃至报错,例如在 A + B Problem 中的输出语句忘加分号就会产生下列情况:
1 | xenonwzh@XenonWZH-Laptop:~$ g++ test.cpp -O2 -o test |
该情况为报错,导致程序无法通过编译。
又例如在程序中定义了一个变量但始终未使用,编译将出现下列情况:
1 | xenonwzh@XenonWZH-Laptop:~$ g++ test.cpp -O2 -Wall -o test |
该情况为警告,程序可以通过编译,但可能在运行中得不到想要的答案,若你对自己的程序很有把握可以忽略警告。
产生更多的警告
由于 GCC 能产生的警告少之又少,同时如 =
与
==
不分等常见错误在 GCC
的默认设置下不会警告,所以我们一般会在编译中添加参数以生成更多的警告,用法如下:
1 | g++ test.cpp -Wall |
利用该命令就可以产生如上一个例子的警告。
忽略特定的警告
由于开启了 -Wall
容易误伤,所以我们可以利用参数忽略特定的警告。
例如我们使用了 scanf
函数,但是 GCC
警告我们没有使用该函数的返回值:
1 | test.cpp: In function ‘int main()’: |
我们可以在其中提取警告的类型。我们看到了
[-Wunused-result]
,说明该类型为
unused-result
。
我们可以使用 -Wno
参数来忽略警告,使用时应在
-Wno
后紧跟警告类型,例子如下:
1 | g++ test.cpp -Wall -Wno-unused-result |
接下来就没有烦人的未使用 scanf
返回值的警告了。
宏定义
我们可以利用 GCC 编译来代替 C++ 中简单的宏定义。
参数为 -D
,使用时应紧跟定义宏。例子如下:
1 | g++ test.cpp -DDEBUG |
其中 -DDEBUG
相当于在 test.cpp
中添加下列语句:
1 |
该参数可在调试或其他场合中使用,非常方便。
例如把调试的语句在定义 DEBUG 宏时才执行,文件输入输出在没定义 DEBUG 时执行,在考场上可有效避免非知识原因的爆 0。
同时注意在绝大多数 OJ 编译代码时参数都含有
-DONLINE_JUDGE
,可以利用该特性提升刷题体验。