gcc, g++ - GNU 工程的 C 和 C++ 编译器 (egcs-1.1.2)

时间:2023-03-09 13:23:24
gcc, g++ - GNU 工程的 C 和 C++ 编译器 (egcs-1.1.2)

总览 (SYNOPSIS)

gcc [ option | filename ]...
g++ [ option | filename ]...

警告 (WARNING)

本手册页 内容 摘自 GNU C 编译器 的 完整文档, 仅限于 解释 选项 的 含义.

除非 有人 自愿 维护, 否则 本手册页 不再 更新. 如果 发现 手册页 和 软件之间 有所矛盾, 请 查对 Info 文件, Info 文件 是 权威
文档.

如果 我们 发觉 本手册页 的 内容 由于 过时 而 导致 明显 的 混乱 和 抱怨 时, 我们 就 停止 发布 它. 不可能有 其他 选择, 象 更新
Info 文件 同时 更新 man 手册, 因为 其他 维护 GNU CC 的 工作 没有 留给 我们 时间 做 这个. GNU 工程 认为 man 手册 是
过时产物, 应该 把 时间 用到 别的地方.

如果 需要 完整 和 最新 的 文档, 请 查阅 Info 文件 `gcc' 或 Using and Porting GNU CC
(for version 2.0) (使用和移植 GNU CC 2.0)
手册. 二者 均 来自 Texinfo 原文件
gcc.texinfo.

描述 (DESCRIPTION)

C 和 C++ 编译器 是 集成的. 他们 都要 用 四个步骤 中的 一个 或 多个 处理输入文件:
预处理(preprocessing), 编译(compilation), 汇编(assembly) 和 连接(linking). 源文件后缀名 标识 源文件 的
语言, 但是 对 编译器 来说, 后缀名 控制着 缺省设定:

gcc
认为 预处理后的 文件 (.i) 是 C 文件, 并且 设定 C 形式 的 连接.
g++
认为 预处理后的 文件 (.i) 是 C++ 文件, 并且 设定 C++ 形式 的 连接.

源文件后缀名 指出 语言种类 以及 后期 的 操作:

.c      C 源程序; 预处理, 编译, 汇编
.C C++ 源程序; 预处理, 编译, 汇编
.cc C++ 源程序; 预处理, 编译, 汇编
.cxx C++ 源程序; 预处理, 编译, 汇编
.m Objective-C 源程序; 预处理, 编译, 汇编
.i 预处理后的 C 文件; 编译, 汇编
.ii 预处理后的 C++ 文件; 编译, 汇编
.s 汇编语言源程序; 汇编
.S 汇编语言源程序; 预处理, 汇编
.h 预处理器文件; 通常 不出现在 命令行 上

其他 后缀名 的 文件 被传递 给 连接器(linker). 通常 包括:

.o      目标文件 (Object file)
.a 归档库文件 (Archive file)

除非 使用了 -c, -S, 或 -E 选项 (或者 编译错误 阻止了 完整 的 过程), 否则 连接 总是 最后的步骤. 在 连接阶段 中, 所有 对应于 源程序 的 .o 文件, -l 库文件, 无法 识别 的 文件名 (包括 指定的 .o 目标文件 和 .a 库文件) 按 命令行中 的 顺序 传递给 连接器.

选项 (OPTIONS)

选项 必须 分立 给出: `-dr' 完全 不同于 `-d -r '.

大多数 `-f' 和 `-W' 选项 有 两个 相反 的 格式: -fname-fno-name (或 -Wname-Wno-name). 这里 只列举 不是 默认选项 的 格式.

下面 是 所有 选项 的 摘要, 按 类型 分组, 解释 放在 后面 的 章节 中.

总体选项 (Overall Option)
-c -S -E -o file -pipe -v -x language
语言选项 (Language Option)
-ansi -fall-virtual -fcond-mismatch -fdollars-in-identifiers
-fenum-int-equiv -fexternal-templates -fno-asm -fno-builtin -fhosted -fno-hosted
-ffreestanding -fno-freestanding -fno-strict-prototype -fsigned-bitfields
-fsigned-char -fthis-is-variable -funsigned-bitfields -funsigned-char
-fwritable-strings -traditional -traditional-cpp -trigraphs
警告选项 (Warning Option)
-fsyntax-only -pedantic -pedantic-errors -w -W -Wall -Waggregate-return
-Wcast-align -Wcast-qual -Wchar-subscript -Wcomment -Wconversion -Wenum-*
-Werror -Wformat -Wid-*-len -Wimplicit -Wimplicit-int
-Wimplicit-function-declaration -Winline -Wlong-long -Wmain -Wmissing-prototypes
-Wmissing-declarations -Wnested-externs -Wno-import -Wparentheses
-Wpointer-arith -Wredundant-decls -Wreturn-type -Wshadow -Wstrict-prototypes
-Wswitch -Wtemplate-debugging -Wtraditional -Wtrigraphs -Wuninitialized -Wunused
-Wwrite-strings
调试选项 (Debugging Option)
-a -dletters -fpretend-float -g -glevel -gcoff -gxcoff
-gxcoff+ -gdwarf -gdwarf+ -gstabs -gstabs+ -ggdb -p -pg -save-temps
-print-file-name=library -print-libgcc-file-name
-print-prog-name=program
优化选项 (Optimization Option)
-fcaller-saves -fcse-follow-jumps -fcse-skip-blocks -fdelayed-branch
-felide-constructors -fexpensive-optimizations -ffast-math -ffloat-store
-fforce-addr -fforce-mem -finline-functions -fkeep-inline-functions
-fmemoize-lookups -fno-default-inline -fno-defer-pop -fno-function-cse
-fno-inline -fno-peephole -fomit-frame-pointer -frerun-cse-after-loop
-fschedule-insns -fschedule-insns2 -fstrength-reduce -fthread-jumps
-funroll-all-loops -funroll-loops -O -O2 -O3
预处理器选项 (Preprocessor Option)
-Aassertion -C -dD -dM -dN -Dmacro[=defn] -E -H
-idirafter dir -include file -imacros file -iprefix
file -iwithprefix dir -M -MD -MM -MMD -nostdinc -P -Umacro
-undef
汇编器选项 (Assembler Option)
-Wa,option
连接器选项 (Linker Option)
-llibrary -nostartfiles -nostdlib -static -shared -symbolic
-Xlinker option -Wl,option -u symbol
目录选项 (Directory Option)
-Bprefix -Idir -I- -Ldir
目标机选项 (Target Option)
-b machine -V version
配置相关选项 (Configuration Dependent Option)
M680x0 选项
-m68000 -m68020 -m68020-40 -m68030 -m68040 -m68881
-mbitfield -mc68000 -mc68020 -mfpa -mnobitfield -mrtd -mshort -msoft-float

VAX 选项
-mg -mgnu -munix

SPARC 选项
-mepilogue -mfpu -mhard-float -mno-fpu -mno-epilogue
-msoft-float -msparclite -mv8 -msupersparc -mcypress

Convex 选项
-margcount -mc1 -mc2 -mnoargcount

AMD29K 选项
-m29000 -m29050 -mbw -mdw -mkernel-registers -mlarge
-mnbw -mnodw -msmall -mstack-check -muser-registers

M88K 选项
-m88000 -m88100 -m88110 -mbig-pic -mcheck-zero-division
-mhandle-large-shift -midentify-revision -mno-check-zero-division
-mno-ocs-debug-info -mno-ocs-frame-position -mno-optimize-arg-area
-mno-serialize-volatile -mno-underscores -mocs-debug-info -mocs-frame-position
-moptimize-arg-area -mserialize-volatile -mshort-data-num -msvr3 -msvr4
-mtrap-large-shift -muse-div-instruction -mversion-03.00 -mwarn-passed-structs

RS6000 选项
-mfp-in-toc -mno-fop-in-toc

RT 选项
-mcall-lib-mul -mfp-arg-in-fpregs -mfp-arg-in-gregs
-mfull-fp-blocks -mhc-struct-return -min-line-mul -mminimum-fp-blocks
-mnohc-struct-return

MIPS 选项
-mcpu=cpu type -mips2 -mips3 -mint64 -mlong64
-mmips-as -mgas -mrnames -mno-rnames -mgpopt -mno-gpopt -mstats -mno-stats
-mmemcpy -mno-memcpy -mno-mips-tfile -mmips-tfile -msoft-float -mhard-float
-mabicalls -mno-abicalls -mhalf-pic -mno-half-pic -G num -nocpp

i386 选项
-m486 -mno-486 -msoft-float -mno-fp-ret-in-387

HPPA 选项
-mpa-risc-1-0 -mpa-risc-1-1 -mkernel -mshared-libs
-mno-shared-libs -mlong-calls -mdisable-fpregs -mdisable-indexing
-mtrailing-colon

i960 选项
-mcpu-type -mnumerics -msoft-float
-mleaf-procedures -mno-leaf-procedures -mtail-call -mno-tail-call -mcomplex-addr
-mno-complex-addr -mcode-align -mno-code-align -mic-compat -mic2.0-compat
-mic3.0-compat -masm-compat -mintel-asm -mstrict-align -mno-strict-align
-mold-align -mno-old-align

DEC Alpha 选项
-mfp-regs -mno-fp-regs -mno-soft-float -msoft-float

System V 选项
-G -Qy -Qn -YP,paths -Ym,dir

代码生成选项 (Code Generation Option)
-fcall-saved-reg -fcall-used-reg -ffixed-reg
-finhibit-size-directive -fnonnull-objects -fno-common -fno-ident
-fno-gnu-linker -fpcc-struct-return -fpic -fPIC -freg-struct-return
-fshared-data -fshort-enums -fshort-double -fvolatile -fvolatile-global
-fverbose-asm

总体选项 (Overall Option)

-x language
明确 指出 后面 输入文件 的 语言 为 language (而不是 从 文件名后缀 得到的 默认选择). 这个选项 应用于 后面
所有的输入文件, 直到 遇着 下一个 `-x' 选项. language 的 可选值 有 `c',
`objective-c', `c-header', `c++', `cpp-output',
`assembler', 和 `assembler-with-cpp'.
-x none
关闭 任何 对 语种 的 明确说明, 因此 依据 文件名后缀 处理 后面 的 文件 (就象是 从未 使用过 `-x' 选项).

如果 只操作 四个阶段 (预处理, 编译, 汇编, 连接) 中的 一部分, 可以 使用 `-x' 选项 (或 文件名后缀) 告诉
gcc 从 哪里 开始, 用 `-c', `-S', 或 `-E' 选项 告诉 gcc
哪里 结束. 注意, 某些 选项组合 (例如, `-x cpp-output -E') 使 gcc 不作 任何事情.

-c
编译 或 汇编 源文件, 但是 不作 连接. 编译器 输出 对应于 源文件 的 目标文件.

缺省情况下, GCC 通过 用 `.o' 替换 源文件名后缀 `.c', `.i', `.s',
等等, 产生 目标文件名. 可以 使用 -o 选项 选择 其他 名字.

GCC 忽略 -c 选项 后面 任何 无法 识别 的 输入文件 (他们 不需要 编译 或 汇编).

-S
编译 后 即停止, 不进行 汇编. 对于 每个 输入的 非汇编语言 文件, 输出文件 是 汇编语言 文件.

缺省情况下, GCC 通过 用 `.o' 替换 源文件名后缀 `.c', `.i', 等等, 产生 目标文件名.
可以 使用 -o 选项 选择 其他 名字.

GCC 忽略 任何 不需要 编译 的 输入文件.

-E
预处理 后 即停止, 不进行 编译. 预处理后的 代码 送往 标准输出.

GCC 忽略 任何 不需要 预处理 的 输入文件.

-o file
指定 输出文件 为 file. 该选项 不在乎 GCC 产生 什么 输出, 无论是 可执行文件, 目标文件, 汇编文件 还是 预处理后的
C 代码.

由于 只能 指定 一个 输出文件, 因此 编译 多个 输入文件 时, 使用 `-o' 选项 没有 意义, 除非 输出 一个 可执行文件.

如果 没有 使用 `-o' 选项, 默认的 输出 结果 是: 可执行文件 为 `a.out',
`source.suffix ' 的 目标文件 是`source.o', 汇编文件 是
`source.s', 而 预处理后的 C 源代码 送往 标准输出.

-v
(在 标准错误) 显示 执行 编译 阶段 的 命令. 同时 显示 编译器 驱动程序, 预处理器, 编译器 的 版本号.
-pipe
在 编译过程 的 不同 阶段 间 使用 管道 而非 临时文件 进行 通信. 这个 选项 在 某些 系统 上 无法 工作, 因为 那些 系统 的 汇编器
不能 从 管道读取 数据. GNU 的 汇编器 没有 这个问题.

语言选项 (LANGUAGE OPTIONS)

下列 选项 控制 编译器 能够 接受 的 C "方言":

-ansi
支持 符合 ANSI 标准的 C 程序.

这样 就会 关闭 GNU C 中 某些 不兼容 ANSI C 的 特性, 例如 asm, inline
typeof 关键字, 以及 诸如 unixvax 这些 表明 当前系统 类型 的 预定义宏. 同时 开启
不受欢迎 和 极少使用的 ANSI trigraph 特性, 以及 禁止 `$' 成为 标识符 的 一部分.

尽管 使用了 `-ansi' 选项, 下面 这些 可选的 关键字, __asm__,
__extension__, __inline____typeof__ 仍然 有效. 你 当然 不会 把 他们
用在 ANSI C 程序 中, 但可以 把 他们 放在头文件 里, 因为 编译 包含 这些 头文件 的 程序 时, 可能会 指定 `-ansi'
选项. 另外一些 预定义宏, 如 __unix____vax__, 无论 有没有 使用 `-ansi' 选项,
始终 有效.

使用 `-ansi' 选项 不会 自动 拒绝 编译 非ANSI程序, 除非 增加 `-pedantic' 选项 作为
`-ansi' 选项 的 补充.

使用 `-ansi' 选项 的 时候, 预处理器 会 预定义 一个 __STRICT_ANSI__ 宏. 有些 头文件 关注
此宏, 以 避免 声明 某些函数, 或者 避免 定义 某些宏, 这些 函数 和 宏 不被 ANSI 标准 调用; 这样 就不会 干扰 在 其他地方 使用
这些名字 的 程序 了.

-fno-asm
不把 asm, inlinetypeof 当作 关键字, 因此 这些 词 可以 用做 标识符. 用
__asm__, __inline____typeof__ 能够 替代 他们. `-ansi'
隐含声明了 `-fno-asm'.
-fno-builtin
不接受 不是 两个 下划线 开头 的 内建函数 (built-in function). 目前 受影响 的 函数 有 _exit,
abort, abs, alloca, cos, exit, fabs,
labs, memcmp, memcpy, sin, sqrt,
strcmp, strcpy, 和 strlen.

`-ansi' 选项 能够 阻止 alloca_exit 成为 内建函数.

-fhosted
按 宿主环境 编译; 他 隐含 声明了 `-fbuiltin' 选项, 而且 警告 不正确的 main 函数 声明.
-ffreestanding
按 独立环境 编译; 他 隐含 声明了 `-fno-builtin' 选项, 而且 对 main 函数 没有 特别要求.

(译注: 宿主环境 (hosted environment) 下 所有的 标准库 可用, main 函数 返回一个 int 值, 典型例子 是 除了 内核
以外 几乎 所有的 程序. 对应的 独立环境 (freestanding environment) 不存在 标准库, 程序 入口 也 不一定是 main,
最明显的 例子 就是 操作系统内核. 详情 参考 gcc 网站 最近的 资料)

-fno-strict-prototype
对于 没有 参数 的 函数声明, 例如 `int foo ();', 按 C 风格 处理---即 不说明 参数 个数 或 类型. (仅针对
C++). 正常情况下, 这样的 函数 foo 在 C++ 中 意味着 参数 为 空.
-trigraphs
支持 ANSI C trigraphs. `-ansi' 选项 隐含声明了 `-trigraphs'.
-traditional
试图 支持 传统 C 编译器 的 某些方面. 详见 GNU C 手册, 我们 已经把 细节清单从这里 删除, 这样 当内容 过时后, 人们 也不会 埋怨
我们.

除了 一件事: 对于 C++ 程序 (不是 C), `-traditional' 选项 带来 一个 附加效应, 允许 对
this 赋值. 他 和 `-fthis-is-variable' 选项 的 效果 一样.

-traditional-cpp
试图 支持 传统 C 预处理器 的 某些方面. 特别是 上面 提到 有关 预处理器 的内容, 但是 不包括 `-traditional'
选项 的 其他 效应.
-fdollars-in-identifiers
允许 在 标识符(identifier) 中 使用 `$' 字符 (仅针对 C++). 你 可以 指定
`-fno-dollars-in-identifiers' 选项 显明 禁止 使用 `$' 符. (GNU C++ 在 某些
目标系统 缺省允许 `$' 符, 但不是 所有系统.)
-fenum-int-equiv
允许 int 类型 到 枚举类型 (enumeration) 的 隐式转换 (仅限于 C++). 正常情况下 GNU C++ 允许 从
enumint 的 转换, 反之则 不行.
-fexternal-templates
为 模板声明 (template declaration) 产生 较小的 代码 (仅限于 C++), 方法 是 对于 每个 模板函数 (template
function), 只在 定义 他们 的 地方生成 一个 副本. 想要 成功 使用 这个选项, 你 必须 在 所有 使用 模板 的 文件 中, 标记
`#pragma implementation' (定义) 或 `#pragma interface' (声明).

当 程序 用 `-fexternal-templates' 编译 时, 模板实例 (template instantiation) 全部是
外部类型. 你 必须 让 需要的 实例 在 实现文件 中 出现. 可以 通过 typedef 实现 这一点, 他 引用 所需的 每个 实例.
相对应的, 如果 编译时 使用 缺省选项 `-fno-external-templates', 所有 模板实例 明确的 设为 内置.

-fall-virtual
所有 可能的 成员函数 默认为 虚函数. 所有的 成员函数 (除了 构造子函数 和 newdelete 成员操作符)
视为 所在类 的 虚函数.

这 不表明 每次 调用 成员函数 都将 通过 内部 虚函数表. 有些 情况 下, 编译器 能够 判断出 可以 直接 调用 某个 虚函数; 这时 就 直接
调用.

-fcond-mismatch
允许 条件表达式 的 第二 和 第三个 参数 的 类型 不匹配. 这种 表达式 的 值 是 void.
-fthis-is-variable
允许 对 this 赋值 (仅对 C++). 合并 用户自定义 的 *存储管理 机制 到 C++ 后, 使 可赋值 的
`this' 显得 不合时宜. 因此, 默认 情况 下, 类成员函数 内部 对 this 赋值 是 无效操作. 然而 为了
向后兼容, 你 可以 通过 `-fthis-is-variable' 选项 使 这种 操作 有效.
-funsigned-char
char 定义为 无符号 类型, 如同 unsigned char.

各种 机器 都有 自己 缺省的 char 类型. 既 可能 是 unsigned char 也 可能是 signed
char
.

理想情况下, 当 依赖于 数据的 符号性 时, 一个 可移植程序 总是 应该 使用 signed charunsigned
char
. 但是 许多 程序 已经 写成 只用 简单的 char, 并且 期待 这是 有符号数 (或者 无符号数, 具体情况 取决于 编写
程序的 目标机器). 这个选项, 和 它的 反义选项, 使 那样的 程序 工作在 对应的默认值 上.

char 的 类型 始终 应该 明确定义 为 signed charunsigned char, 即使 它
表现的 和 其中之一 完全一样.

-fsigned-char
char 定义为 有符号 类型, 如同 signed char.

这个 选项 等同于 `-fno-unsigned-char', 他是 the negative form of
`-funsigned-char' 的 相反 选项. 同样, `-fno-signed-char' 等价于
`-funsigned-char'.

-fsigned-bitfields
-funsigned-bitfields
-fno-signed-bitfields
-fno-unsigned-bitfields
如果 没有 明确 声明 `signed' 或 `unsigned' 修饰符, 这些 选项 用来 定义 有符号位域
(bitfield) 或 无符号位域. 缺省情况下, 位域 是 有符号 的, 因为 他们 继承的 基本 整数类型, 如 int, 是 有符号数.

然而, 如果 指定了 `-traditional' 选项, 位域 永远 是 无符号数.

-fwritable-strings
把 字符串常量 存储到 可写数据段, 而且 不做 特别 对待. 这是 为了 兼容 一些 老程序, 他们 假设 字符串常量 是 可写的.
`-traditional' 选项 也有 相同 效果.

篡改 字符串常量 是一个 非常 糟糕的 想法; ``常量'' 就应该是 常量.

预处理器选项 (Preprocessor Option)

下列 选项 针对 C 预处理器, 预处理器 用在 正式 编译 以前, 对 C
源文件进行 某种处理.

如果 指定了 `-E' 选项, GCC 只进行 预处理 工作. 下面的 某些 选项 必须 和 `-E' 选项 一起 才
有意义, 因为 他们的 输出结果 不能 用于 编译.

-include file
在 处理 常规 输入文件 之前, 首先 处理 文件 file, 其结果是, 文件 file 的 内容 先得到 编译.
命令行上 任何 `-D' 和 `-U' 选项 永远 在 `-include file' 之前 处理,
无论 他们 在 命令行上 的 顺序 如何. 然而 `-include' 和 `-imacros' 选项 按 书写顺序 处理.
-imacros file
在 处理 常规 输入文件 之前, 首先 处理 文件 file, 但是 忽略 输出结果. 由于 丢弃了 文件 file
输出内容, `-imacros file' 选项 的 唯一 效果 就是 使 文件 file 中 的 宏定义 生效,
可以 用于 其他 输入文件. 在 处理 `-imacrosfile' 选项 之前, 预处理器 首先 处理 `-D' 和
`-U' 选项, 并不在乎 他们 在 命令行上 的 顺序. 然而 `-include' 和 `-imacros' 选项
按 书写顺序 处理.
-idirafter dir
把 目录 dir 添加到 第二包含路径 中. 如果 某个 头文件 在 主包含路径 (用`-I' 添加的 路径) 中 没有
找到, 预处理器 就搜索 第二包含路径.
-iprefix prefix
指定 prefix 作为 后续 `-iwithprefix' 选项 的 前缀.
-iwithprefix dir
把 目录 添加到 第二包含路径 中. 目录名 由 prefixdir 合并 而成, 这里 prefix
被 先前的 `-iprefix' 选项 指定.
-nostdinc
不要 在 标准系统目录 中 寻找 头文件. 只 搜索 `-I' 选项 指定的 目录 (以及 当前目录, 如果 合适).

结合 使用 `-nostdinc' 和 `-I-' 选项, 你 可以 把 包含文件 搜索 限制在 显式 指定的 目录.

-nostdinc++
不要 在 C++ 专用标准目录 中 寻找 头文件, 但是 仍然 搜索 其他 标准目录. (当 建立 `libg++' 时 使用
这个选项.)
-undef
不要 预定义 任何 非标准宏. (包括 系统结构 标志).
-E
仅运行 C 预处理器. 预处理 所有 指定的 C 源文件, 结果 送往 标准输出或 指定的 输出文件.
-C
告诉 预处理器 不要 丢弃 注释. 配合 `-E' 选项 使用.
-P
告诉 预处理器 不要 产生 `#line' 命令. 配合 `-E' 选项 使用.
-M  [ -MG ]
告诉 预处理器 输出 一个 适合 make 的 规则, 用于 描述 各目标文件的 依赖 关系. 对于 每个 源文件, 预处理器 输出 一个
make 规则, 该规则 的 目标项 (target) 是 源文件 对应的 目标文件名, 依赖项 (dependency) 是 源文件中
`#include 引用的 所有文件. 生成的 规则 可以是 单行, 但如果 太长, 就用 `\'-换行符 续成 多行. 规则
显示在 标准输出, 不产生 预处理过的 C 程序.

`-M' 隐含了 `-E' 选项.

`-MG' 要求 把 缺失的 头文件 按 存在 对待, 并且 假定 他们 和 源程序文件在 同一目录 下. 必须 和 `-M'
选项 一起用.

-MM  [ -MG ]
和 `-M' 选项 类似, 但是 输出结果 仅涉及 用户头文件, 象 这样 `#include file"'.
忽略 系统头文件 如 `#include <file>'.
-MD
和 `-M' 选项 类似, 但是 把 依赖 信息 输出在 文件中, 文件名 通过 把 输出文件名末尾的 `.o' 替换为
`.d' 产生. 同时 继续 指定的 编译工作 ---`-MD' 不象 `-M' 那样 阻止 正常的 编译任务.

Mach 的 实用工具 `md' 能够 合并 `.d' 文件, 产生 适用于 `make' 命令 的 单一的
依赖文件.

-MMD
和 `-MD' 选项 类似, 但是 输出结果 仅涉及 用户头文件, 忽略 系统头文件.
-H
除了 其他 普通 的 操作, GCC 显示 引用过的 头文件 名.
-Aquestion(answer)
如果 预处理器 做 条件测试, 如 `#if
#
question(answer)', 该选项 可以 断言 (Assert)
question 的 答案 是 answer. -A-' 关闭 一般用于 描述 目标机 的 标准 断言.
-Dmacro
定义 宏 macro, 宏 的 内容 定义为 字符串 `1'.
-Dmacro=defn
定义 宏 macro 的 内容 为 defn. 命令行 上 所有的 `-D' 选项 在 `-U'
选项 之前 处理.
-Umacro
取消 宏 macro. `-U' 选项 在 所有的 `-D' 选项 之后 处理, 但是 优先于 任何
`-include' 或 `-imacros' 选项.
-dM
告诉 预处理器 输出 有效的 宏定义 列表 (预处理 结束时 仍然 有效的 宏定义). 该选项 需 结合 `-E' 选项 使用.
-dD
告诉 预处理器 把 所有的 宏定义 传递到 输出端, 按照 出现的 顺序 显示.
-dN
和 `-dD'选项 类似, 但是 忽略 宏的 参量 或 内容. 只在 输出端 显示 `#define
name.

汇编器选项 (ASSEMBLER OPTION)

-Wa,option
把 选项 option 传递给 汇编器. 如果 option 含有 逗号, 就在 逗号 处 分割成 多个 选项.

连接器选项 (LINKER OPTION)

下面的 选项 用于 编译器 连接 目标文件, 输出 可执行文件 的 时候. 如果 编译器 不进行
连接, 他们 就 毫无意义.

object-file-name
如果 某些文件 没有 特别明确的 后缀 a special recognized suffix, GCC 就 认为 他们 是 目标文件 或 库文件.
(根据 文件内容, 连接器 能够 区分目标文件 和 库文件). 如果 GCC 执行 连接 操作, 这些 目标文件 将 成为连接器 的 输入文件.
-llibrary
连接 名为 library 的 库文件.

连接器 在 标准搜索目录 中 寻找 这个 库文件, 库文件 的 真正 名字 是 `liblibrary.a'. 连接器 会
当做 文件名 得到 准确 说明 一样 引用 这个文件.

搜索目录 除了 一些 系统标准目录 外, 还包括 用户 以 `-L' 选项 指定 的 路径.

一般说来 用 这个方法 找到的 文件 是 库文件---即由 目标文件 组成的 归档文件 (archive file). 连接器 处理 归档文件 的 方法
是: 扫描 归档文件, 寻找 某些 成员, 这些 成员 的 符号 目前 已 被引用, 不过 还没有 被定义. 但是, 如果 连接器 找到 普通的 目标文件,
而不是 库文件, 就把 这个 目标文件按 平常方式 连接 进来. 指定 `-l' 选项 和 指定 文件名 的 唯一 区别 是,
`-l选项 用 `lib' 和 `.a' 把 library 包裹 起来, 而且 搜索 一些 目录.

-lobjc
这个 -l 选项 的 特殊形式 用于 连接 Objective C 程序.
-nostartfiles
不连接 系统 标准启动文件, 而 标准库文件 仍然 正常 使用.
-nostdlib
不连接 系统 标准启动文件 和 标准库文件. 只把 指定的 文件 传递给 连接器.
-static
在 支持 动态连接 (dynamic linking) 的 系统 上, 阻止 连接 共享库. 该选项 在 其他系统上 无效.
-shared
生成 一个 共享目标文件, 他 可以 和 其他 目标文件 连接 产生 可执行文件. 只有 部分 系统 支持 该选项.
-symbolic
建立 共享目标文件 的 时候, 把 引用 绑定到 全局符号上. 对 所有 无法解析的 引用 作出 警告 (除非 用 连接编辑选项
`-Xlinker -z -Xlinker defs' 取代). 只有 部分 系统 支持 该选项.
-Xlinker option
把 选项 option 传递给 连接器. 可以 用 他 传递 系统 特定的 连接 选项, GNU CC 无法 识别 这些 选项.

如果 需要 传递 携带 参数 的 选项, 你 必须 使用 两次 `-Xlinker', 一次 传递 选项, 另一次 传递 他的 参数.
例如, 如果 传递 `-assert definitions', 你 必须 写成 `-Xlinker -assert -Xlinker
definitions
', 而不能 写成 `-Xlinker "-assert definitions"', 因为 这样 会把 整个
字符串 当做 一个 参数 传递, 显然 这 不是连接器 期待的.

-Wl,option
把 选项 option 传递给 连接器. 如果 option 中 含有 逗号, 就在 逗号 处 分割成 多个 选项.
-u symbol
使 连接器 认为 取消了 symbol 的 符号定义, 从而 连接 库模块 以 取得 定义. 你 可以 使用 多个 `-u'
选项, 各自 跟上 不同的 符号, 使得 连接器 调入 附加的 库模块.

目录选项 (DIRECTORY OPTION)

下列 选项 指定 搜索路径, 用于 查找 头文件, 库文件, 或 编译器 的 某些成员:

-Idir
在 头文件 的 搜索路径 列表 中 添加 dir 目录.
-I-
任何 在 `-I-' 前面 用 `-I' 选项 指定 的 搜索路径 只适用于 `#include
"
file"' 这种 情况; 他们 不能 用来 搜索 `#include
<
file>' 包含 的 头文件.

如果 用 `-I' 选项 指定的 搜索路径 位于 `-I-' 选项 后面, 就可以 在 这些 路径 中 搜索 所有的
`#include' 指令. (一般说来 -I 选项 就是 这么 用的.)

还有, `-I-' 选项 能够 阻止 当前目录 (存放 当前 输入文件 的 地方) 成为 搜索 `#include
"
file"' 的 第一选择. 没有 办法 克服 `-I-' 选项 的 这个效应. 你 可以 指定
`-I.' 搜索 那个目录, 它 在 调用 编译器 时 是 当前目录. 这 和 预处理器 的 默认行为 不完全 一样, 但是 结果 通常
令人满意.

`-I-' 不影响 使用 系统标准目录, 因此, `-I-' 和 `-nostdinc' 是 不同的 选项.

-Ldir
在 `-l' 选项 的 搜索路径 列表 中 添加 dir 目录.
-Bprefix
这个选项 指出 在何处 寻找 可执行文件, 库文件, 以及 编译器 自己 的 数据文件.

编译器 驱动程序 需要 执行 某些 下面的 子程序: `cpp', `cc1' (或 C++ 的
`cc1plus'), `as' 和 `ld'. 他 把 prefix 当作 欲执行的 程序 的 前缀,
既可以 包括 也可以 不包括 `machine/version/'.

对于 要运行的 子程序, 编译器 驱动程序 首先 试着 加上 `-B' 前缀 (如果存在). 如果 没有 找到 文件, 或 没有 指定
`-B' 选项, 编译器 接着 会 试验 两个 标准 前缀 `/usr/lib/gcc/' 和
`/usr/local/lib/gcc-lib/'. 如果 仍然 没能够 找到 所需文件, 编译器 就在 `PATH' 环境变量
指定的 路径 中 寻找 没加 任何 前缀 的 文件名.

如果 有需要, 运行时 (run-time) 支持文件 `libgcc.a' 也在 `-B' 前缀 的 搜索 范围 之内.
如果 这里 没有 找到, 就在 上面 提到的两个 标准 前缀 中 寻找, 仅此而已. 如果 上述 方法 没有 找到 这个 文件, 就 不连接 他了. 多数 情况
的 多数 机器 上, `libgcc.a' 并非 必不可少.

你 可以 通过 环境变量 GCC_EXEC_PREFIX 获得 近似的 效果; 如果 定义了 这个 变量, 其值 就和 上面 说的 一样用做
前缀. 如果 同时 指定了 `-B' 选项 和 GCC_EXEC_PREFIX 变量, 编译器 首先 使用 `-B'
选项, 然后 才尝试 环境变量值.

警告选项 (WARNING OPTION)

警告 是 针对 程序结构 的 诊断信息, 程序 不一定 有错误, 而是 存在风险, 或者 可能 存在
错误.

下列 选项 控制 GNU CC 产生 的 警告 的 数量 和 类型:

-fsyntax-only
检查 程序 中 的 语法错误, 但是 不产生 输出信息.
-w
禁止 所有 警告信息.
-Wno-import
禁止 所有 关于 #import 的 警告信息.
-pedantic
打开 完全服从 ANSI C 标准 所需的 全部 警告诊断; 拒绝接受 采用了被禁止的 语法扩展 的 程序.

无论 有没有 这个 选项, 符合 ANSI C 标准 的 程序 应该 能够 被 正确 编译 (虽然 极少数 程序 需要 `-ansi'
选项). 然而, 如果 没有 这个 选项, 某些 GNU 扩展 和 传统 C 特性也 得到 支持. 使用 这个 选项 可以 拒绝 这些 程序. 没有 理由 使用
这个选项, 他 存在 只是 为了 满足 一些 书呆子 (pedant).

对于 替选关键字 (他们 以 `__' 开始 和 结束) `-pedantic' 不会 产生 警告信息. Pedantic 也
不警告 跟在 __extension__ 后面 的 表达式. 不过 只应该 在 系统头文件 中 使用 这种 转义措施, 应用程序 最好 避免.

-pedantic-errors
该 选项 和 `-pedantic' 类似, 但是 显示 错误 而不是 警告.
-W
对 下列 事件 显示 额外的 警告信息:
   *
非易变自动变量 (nonvolatile automatic variable) 可能 在 调用 longjmp 时 发生 改变. 这些
警告 仅在 优化编译 时 发生.

编译器 只知道 对 setjmp 的 调用, 他 不可能 知道 会 在哪里 调用 longjmp, 事实上 一个 信号处理例程
可以 在 程序 的 任何 地点 调用 他. 其结果是, 即使 程序 没有 问题, 你 也可能会 得到 警告, 因为 无法 在可能 出现 问题 的 地方 调用
longjmp.

   *
既可以 返回 值, 也可以 不返回 值 的 函数. (缺少 结尾 的 函数体 被看作不返回 函数值) 例如, 下面的 函数 将 导致 这种 警告:
foo (a)
{
if (a > 0)
return a;
}

由于 GNU CC 不知道 某些 函数 永不返回 (含有 abortlongjmp), 因此 有可能 出现 虚假 警告.

   *
表达式语句 或 逗号表达式 的 左侧 没有 产生 作用 (side effect). 如果要 防止 这种 警告, 应该把 未使用的 表达式 强制转换 为 void 类型. 例如, 这样的 表达式 `x[i,j]' 会 导致 警告, 而 `x[(void)i,j]' 就 不会.
   *
无符号数 用 `>' 或 `<=' 和 零 做比较.
-Wimplicit-int
警告 没有 指定 类型 的 声明.
-Wimplicit-function-declaration
警告 在 声明 之前 就 使用 的 函数.
-Wimplicit
同 -Wimplicit-int 和 -Wimplicit-function-declaration.
-Wmain
如果 把 main 函数 声明 或 定义 成 奇怪 的 类型, 编译器 就 发出 警告. 典型情况下, 这个 函数 用于 外部连接, 返回 int 数值, 不需要 参数, 或 指定 两个 参数.
-Wreturn-type
如果 函数 定义了 返回类型, 而 默认 类型 是 int 型, 编译器 就 发出 警告. 同时 警告 那些 不带 返回值 的 return 语句, 如果 他们 所属的 函数 并非 void 类型.
-Wunused
如果 某个 局部变量 除了 声明 就 没再 使用, 或者 声明了 静态函数 但是 没有定义, 或者 某条 语句 的 运算结果 显然 没有 使用, 编译器 就 发出 警告.
-Wswitch
如果 某条 switch 语句 的 参数 属于 枚举类型, 但是 没有 对应的 case 语句 使用 枚举元素, 编译器 就 发出 警告. ( default 语句 的 出现 能够 防止 这个 警告.) 超出 枚举 范围 的 case 语句 同样 会 导致 这个 警告.
-Wcomment
如果 注释起始序列 `/*' 出现在 注释 中, 编译器 就 发出 警告.
-Wtrigraphs
警告 任何 出现的 trigraph (假设 允许 使用 他们).
-Wformat
检查 对 printfscanf 等 函数 的 调用, 确认 各个 参数 类型 和 格式串 中的 一致.
-Wchar-subscripts
警告 类型 是 char 的 数组 下标. 这是 常见 错误, 程序员 经常 忘记 在 某些 机器 上 char 有 符号.
-Wuninitialized
在 初始化 之前 就 使用 自动变量.

这些警告 只可能 做 优化编译 时 出现, 因为 他们 需要 数据流信息, 只有做 优化 的 时候 才 估算 数据流信息. 如果 不指定 `-O' 选项, 就不会 出现 这些警告.

这些警告 仅针对 等候 分配 寄存器 的 变量. 因此 不会 发生在 声明为 volatile 的 变量 上面, 不会 发生在 已经 取得 地址 的 变量, 或 长度 不等于 1, 2, 4, 8 字节 的 变量. 同样 也不会 发生在 结构, 联合 或 数组 上面, 即使 他们 在 寄存器 中.

注意, 如果 某个变量 只 计算了 一个 从未使用过 的 值, 这里 可能 不会 警告. 因为 在 显示 警告 之前, 这样 的 计算 已经 被 数据流分析 删除 了.

这些警告 作为 可选项 是因为 GNU CC 还没有 智能到 判别 所有的 情况, 知道有些 看上去 错误 的 代码 其实 是 正确的. 下面 是 一个 这样的 例子:

{
int x;
switch (y)
{
case 1: x = 1;
break;
case 2: x = 4;
break;
case 3: x = 5;
}
foo (x);
}

如果 y 始终是 1, 2 或 3, 那么 x 总会被 初始化, 但是 GNU CC 不知道 这一点. 下面 是 另一个 普遍案例:

{
int save_y;
if (change_y) save_y = y, y = new_y;
...
if (change_y) y = save_y;
}

这里 没有 错误, 因为 只有 设置了 save_y 才 使用 他.

把 所有 不返回 的 函数 定义为 volatile 可以 避免 某些 似是而非的 警告.

-Wparentheses
在 某些 情况 下 如果 忽略了 括号, 编译器 就 发出 警告.
-Wtemplate-debugging
当 在 C++ 程序 中 使用 template 的 时候, 如果 调试 (debugging) 没有 完全 生效, 编译器 就 发出 警告. (仅用于 C++).
-Wall
结合 所有 上述 的 `-W' 选项. 通常 我们 建议 避免 这些 被警告的 用法,我们 相信, 恰当 结合 宏 的 使用 能够 轻易 避免 这些 用法。

剩下的 `-W...' 选项 不包括 在 `-Wall' 中, 因为 我们 认为 在 必要情况 下, 这些 被 编译器 警告 的 程序结构, 可以 合理的 用在 "干净的" 程序 中.

-Wtraditional
如果 某些 程序结构 在 传统 C 中 的 表现 和 ANSI C 不同, 编译器 就 发出 警告.
   *
宏参 出现在 宏体 的 字符串常量 内部. 传统 C 会 替换 宏参, 而 ANSI C 则 视其为 常量 的 一部分.
   *
某个函数 在 块(block) 中 声明为 外部, 但在 块 结束后 才 调用.
   *
switch 语句 的 操作数 类型 是 long.
-Wshadow
一旦 某个 局部变量 屏蔽了 另一个 局部变量, 编译器 就 发出 警告.
-Wid-*-len
一旦 两个 确定的 标识符 具有 相同的 前 len 个 字符, 编译器 就 发出 警告. 他 可以 协助 你 开发 一些 将要在某些 过时的, 危害大脑的 编译器 上 编译 的 程序.
-Wpointer-arith
任何 语句 如果 依赖于 函数类型 的 大小(size) 或者 void 类型 的 大小, 编译器 就 发出 警告. GNU C 为了 便于 计算 void * 指针 和 函数指针, 就把 这些 类型 的 大小 定义 为 1.
-Wcast-qual
一旦 某个 指针 强制类型转换 以便 移除 类型修饰符 时, 编译器 就 发出 警告. 例如, 如果 把 const char * 强制转换 为 普通的 char * 时, 警告 就会 出现.
-Wcast-align
一旦 某个 指针类型 强制转换 时, 导致 目标 所需的 地址对齐 (alignment) 增加, 编译器 就 发出 警告. 例如, 某些 机器 上 只能 在 2 或 4 字节 边界 上 访问 整数, 如果 在 这种 机型 上 把 char * 强制转换 成 int * 类型, 编译器 就 发出 警告.
-Wwrite-strings
规定 字符串常量 的 类型 是 const char[length], 因此, 把 这样的 地址 复制给 non-const char * 指针 将 产生 警告. 这些 警告 能够 帮助 你 在 编译期间 发现 企图 写入 字符串常量 的 代码, 但是 你 必须 非常 仔细 的 在 声明 和 原形 中 使用 const, 否则 他们 只能 带来 麻烦; 所以 我们 没有 让 `-Wall' 提供 这些 警告.
-Wconversion
如果 某函数原形 导致 的 类型转换 和 无函数原形 时的 类型转换 不同, 编译器 就 发出 警告. 这里 包括 定点数 和 浮点数 的 互相转换, 改变 定点数 的 宽度 或 符号, 除非 他们 和 缺省声明 (default promotion) 相同.
-Waggregate-return
如果 定义 或 调用 了 返回 结构 或 联合 的 函数, 编译器 就 发出 警告. (从 语言角度 你 可以 返回 一个 数组, 然而 同样 会 导致 警告.)
-Wstrict-prototypes
如果 函数 的 声明 或 定义 没有 指出 参数类型, 编译器 就 发出 警告. (如果 函数 的 前向引用说明 指出了 参数类型, 则 允许 后面 使用 旧式风格的 函数定义, 而 不会产生 警告.)
-Wmissing-prototypes
如果 没有 预先 声明 函数原形 就 定义了 全局函数, 编译器 就 发出 警告. 即使 函数定义 自身 提供了 函数原形 也会 产生 这个 警告. 他 的 目的是 检查 没有 在 头文件 中 声明 的 全局函数.
-Wmissing-declarations
如果 没有 预先 声明 就 定义了 全局函数, 编译器 就 发出 警告. 即使 函数定义 自身 提供了 函数原形 也会 产生 这个 警告. 这个选项 的 目的是 检查 没有 在 头文件 中 声明 的 全局函数.
-Wredundant-decls
如果 在 同一个 可见域 某定义 多次 声明, 编译器 就 发出 警告, 即使 这些重复声明 有效 并且 毫无差别.
-Wnested-externs
如果 某 extern 声明 出现在 函数 内部, 编译器 就 发出 警告.
-Wenum-*
对于 不同 枚举类型 之间 的 转换 发出 警告 (仅适用于 C++).
-Wlong-long
如果 使用了 long long 类型 就 发出 警告. 该 警告 是 缺省项. 使用 `-Wno-long-long' 选项 能够 防止 这个 警告. `-Wlong-long' 和 `-Wno-long-long' 仅 在 `-pedantic' 之下 才起作用.
-Woverloaded-virtual
(仅适用于 C++.) 在继承类中, 虚函数 的 定义 必须 匹配 虚函数 在 基类中 声明 的 类型特征 (type signature). 当 继承类 声明了 某个函数, 它 可能 是个 错误的 尝试 企图 定义一个 虚函数, 使用 这个 选项 能够 产生 警告: 就是说, 当 某个函数 和 基类 中的 虚函数 同名, 但是 类型特征 不符合 基类的 任何 虚函数, 编译器 将发出 警告.
-Winline
如果 某函数 不能 内嵌(inline), 无论 是 声明为 inline 或者是 指定了 -finline-functions 选项, 编译器 都将 发出 警告.
-Werror
视 警告 为 错误; 出现 任何 警告 即 放弃 编译.

调试选项 (DEBUGGING OPTION)

GNU CC 拥有 许多 特别选项, 既可以 调试 用户的 程序, 也可以 对 GCC 排错:

-g
以 操作系统 的 本地格式 (stabs, COFF, XCOFF, 或 DWARF). 产生 调试信息. GDB 能够 使用 这些 调试信息.

在 大多数 使用 stabs 格式 的 系统 上, `-g' 选项 启动 只有 GDB 才使用 的 额外调试信息; 这些信息 使 GDB 调试效果 更好, 但是 有可能 导致 其他 调试器 崩溃, 或 拒绝 读入 程序. 如果 你 确定 要 控制 是否 生成 额外的 信息, 使用`-gstabs+', `-gstabs', `-gxcoff+', `-gxcoff', `-gdwarf+', 或 `-gdwarf' (见下文).

和 大多数 C 编译器 不同, GNU CC 允许 结合使用 `-g' 和 `-O' 选项. 优化的 代码 偶尔 制造 一些 惊异的 结果: 某些 声明过的 变量根本 不存在; 控制流程 直接 跑到 没有 预料到的 地方; 某些语句 因为 计算结果是 常量 或 已经确定 而 没有 执行; 某些语句 在 其他 地方 执行, 因为 他们被移到 循环 外面 了.

然而 它 证明了 调试 优化的输出 是 可能的. 对 可能 含有 错误 的 程序使用 优化器 是 合理的.

如果 GNU CC 支持 输出 多种 调试信息, 下面的 选项 则 非常有用.

-ggdb
以 本地格式 (如果支持) 输出 调试信息, 尽可能 包括 GDB 扩展.
-gstabs
以 stabs 格式 (如果支持) 输出 调试信息, 不包括 GDB 扩展. 这是 大多数 BSD 系统 上 DBX 使用 的 格式.
-gstabs+
以 stabs 格式 (如果支持) 输出 调试信息, 使用 只有 GNU 调试器 (GDB) 理解的 GNU 扩展. 使用 这些扩展 有可能 导致 其他 调试器 崩溃 或 拒绝读入 程序.
-gcoff
以 COFF 格式 (如果支持) 输出 调试信息. 这是 在 System V 第四版 以前的 大多数 System V 系统 上 SDB 使用 的 格式.
-gxcoff
以 XCOFF 格式 (如果支持) 输出 调试信息. 这是 IBM RS/6000 系统上 DBX 调试器 使用 的 格式.
-gxcoff+
以 XCOFF 格式 (如果支持) 输出 调试信息, 使用 只有 GNU 调试器 (GDB) 理解的 GNU 扩展. 使用 这些扩展 有可能 导致 其他 调试器 崩溃 或 拒绝读入 程序.
-gdwarf
以 DWARF 格式 (如果支持) 输出 调试信息. 这是 大多数 System V 第四版系统 上 SDB 使用 的 格式.
-gdwarf+
以 DWARF 格式 (如果支持) 输出 调试信息, 使用 只有 GNU 调试器 (GDB) 理解的 GNU 扩展. 使用 这些扩展 有可能 导致 其他 调试器 崩溃 或 拒绝读入 程序.

-glevel
-ggdblevel

-gstabslevel
-gcofflevel
-gxcofflevel

-gdwarflevel
请求 生成 调试信息, 同时 用 level 指出 需要 多少 信息. 默认的 level 值 是 2.

Level 1 输出 最少量 的 信息, 仅够 在 不打算 调试 的 程序段 内 backtrace. 包括 函数 和 外部变量 的 描述, 但是 没有
局部变量 和 行号 信息.

Level 3 包含 更多的 信息, 如 程序中出现 的 所有 宏定义. 当 使用 `-g3' 选项 的 时候, 某些 调试器 支持
宏扩展.

-p
产生 额外代码, 用于 输出 profile 信息, 供 分析程序 prof 使用.
-pg
产生 额外代码, 用于 输出 profile 信息, 供 分析程序 gprof 使用.
-a
产生 额外代码, 用于 输出 基本块 (basic block) 的 profile 信息, 它 记录 各个 基本块 的 执行 次数, 供 诸如
tcov 此类 的 程序 分析. 但是 注意, 这个 数据格式 并非 tcov 期待的. 最终 GNU gprof
处理 这些数据.
-ax
产生 额外代码, 用于 从 'bb.in' 文件 读取 基本块 的 profile 参数, 把 profile 的 结果 写到 'bb.out' 文件.
`bb.in' 包含 一张 函数 列表. 一旦 进入 列表 中的 某个 函数, profile 操作就 开始, 离开 最外层 的 函数 后, profile
操作 就 结束. 以 `-' 为 前缀名 的 函数 排除在 profile 操作 之外. 如果 函数名 不是 唯一的, 它 可以 写成
`/path/filename.d:functionname' 来 澄清. `bb.out' 将 列出 一些 有效的文件名. 这四个 函数名 具有 特殊含义:
`__bb_jumps__' 导致 跳转 (jump) 频率 写进 `bb.out'. `__bb_trace__' 导致 基本块 序列 通过 管道 传到
`gzip', 输出 `bbtrace.gz' 文件. `__bb_hidecall__' 导致 从 跟踪 (trace) 中 排除 call 指令.
`__bb_showret__' 导致 在 跟踪 中 包括 返回指令.
-dletters
编译 的 时候, 在 letters 指定 的 时刻 做 调试转储 (dump). 用于 调试 编译器. 大多数 转储 的 文件名 通过
源文件名 添加 字词 获得 (例如 `foo.c.rtl' 或 `foo.c.jump').
-dM
预处理 结束 的 时候 转储 所有的 宏定义, 不输出到 文件.
-dN
预处理 结束 的 时候 转储 所有的 宏名.
-dD
预处理 结束 的 时候 转储 所有的 宏定义, 同时 进行 正常 输出.
-dy
语法分析 (parse) 的 时候 在 标准错误 转储 调试信息.
-dr
RTL 阶段 后 转储到 `file.rtl'.
-dx
仅对 函数 生成 RTL, 而不是 编译. 通常 和 `r' 联用.
-dj
第一次 跳转优化 后 转储到 `file.jump'.
-ds
CSE (包括 有时候 跟在 CSE 后面的 跳转优化) 后 转储到 `file.cse'.
-dL
循环优化 后 转储到 `file.loop'.
-dt
第二次 CSE 处理 (包括 有时候 跟在 CSE 后面的 跳转优化) 后 转储到 `file.cse2'.
-df
流程分析 (flow analysis) 后 转储到 `file.flow'.
-dc
指令组合 (instruction combination) 后 转储到 `file.combine'.
-dS
第一次 指令安排 (instruction schedule) 后 转储到 `file.sched'.
-dl
局部寄存器分配 后 转储到 `file.lreg'.
-dg
全局寄存器分配 后 转储到 `file.greg'.
-dR
第二次 指令安排 (instruction schedule) 后 转储到 `file.sched2'.
-dJ
最后一次 跳转优化 后 转储到 `file.jump2'.
-dd
推迟分支调度 (delayed branch scheduling) 后 转储到 `file.dbr'.
-dk
寄存器-堆栈转换 后 转储到 `file.stack'.
-da
产生 以上 所有的 转储.
-dm
运行结束后, 在 标准错误 显示 内存使用统计.
-dp
在 汇编输出 加注 指明 使用了 哪些 模式 (pattern) 及其 替代模式.
-fpretend-float
交叉编译 的 时候, 假定 目标机 和 宿主机 使用 同样的 浮点格式. 它 导致 输出 错误的 浮点常数, 但是 在 目标机 上 运行 的 时候,
真实的 指令序列 有可能 和 GNU CC 希望 的 一样.
-save-temps
保存 那些 通常 是 ``临时'' 的 中间文件; 置于 当前目录 下, 并且 根据 源文件 命名. 因此, 用 `-c
-save-temps
' 选项 编译 `foo.c ' 会 生成 ` foo.cpp' 和 `foo.s'
以及 `foo.o' 文件.
-print-file-name=library
显示 库文件 library 的 全路径名, 连接 时 会 使用 这个库 --- 其他 什么事情 都不作. 根据 这个选项, GNU CC
既不编译, 也不连接, 仅仅 显示 文件名.
-print-libgcc-file-name
和 `-print-file-name=libgcc.a' 一样.
-print-prog-name=program
类似于 `-print-file-name', 但是 查找 程序 program 如 `cpp'.

优化选项 (OPTIMIZATION OPTION)

这些选项 控制 多种 优化措施:

-O
-O1
优化. 对于 大函数, 优化编译 占用 稍微多 的 时间 和 相当大 的 内存.

不使用 `-O' 选项 时, 编译器 的 目标 是 减少 编译 的 开销, 使 编译结果 能够 调试. 语句 是 独立的: 如果 在
两条语句 之间 用 断点 中止 程序, 你 可以 对任何 变量 重新 赋值, 或者 在 函数体 内 把 程序计数器 指到 其他语句, 以及 从 源程序 中
精确地 获取 你 期待 的 结果.

不使用 `-O' 选项 时, 只有 声明了 register 的 变量 才 分配使用 寄存器. 编译结果 比 不用
`-O' 选项 的 PCC 要 略逊一筹.

使用了 `-O' 选项, 编译器 会试图 减少 目标码 的 大小 和 执行时间.

如果 指定了 `-O' 选项, `-fthread-jumps' 和 `-fdefer-pop' 选项 将被
打开. 在 有 delay slot 的 机器 上, `-fdelayed-branch' 选项 将被 打开. 在 即使 没有 帧指针
(frame pointer) 也支持 调试 的 机器 上, `-fomit-frame-pointer' 选项 将被 打开. 某些机器 上
还可能会 打开 其他选项.

-O2
多优化一些. 除了 涉及 空间 和 速度 交换 的 优化选项, 执行 几乎 所有的优化工作. 例如 不进行 循环展开 (loop unrolling)
和 函数内嵌 (inlining). 和 -O 选项 比较, 这个选项 既增加了 编译时间, 也提高了 生成代码 的 运行效果.
-O3
优化的更多. 除了 打开 -O2 所做的 一切, 它 还 打开 了 -finline-functions 选项.
-O0
不优化.

如果 指定了 多个 -O 选项, 不管 带不带 数字, 最后一个 选项 才是 生效 的 选项.

诸如 `-fflag' 此类 的 选项 描述 一些 机器无关 的 开关. 大多数 开关 具有 肯定 和 否定 两种格式;
`-ffoo' 开关选项 的 否定格式 应该是 `-fno-foo'. 下面的 列表 只展示了 一种 格式 --- 那个 不是
默认选项 的 格式. 你 可以 通过 去掉 或 添加 `no-' 构造出 另一种 格式.

-ffloat-store
不要 在 寄存器 中 存放 浮点变量. 这样 可以 防止 某些 机器 上 不希望的 过高 精度, 如 68000 的 浮点寄存器 (来自 68881)
保存的 精度 超过了 double 应该 具有的 精度.

对于 大多数 程序, 过高 精度 只有 好处. 但是 有些 程序 严格 依赖于 IEEE 浮点数的 定义. 对 这样的 程序 可以 使用
`-ffloat-store' 选项.

-fmemoize-lookups
-fsave-memoized
使用 探索法 (heuristic) 进行 更快的 编译 (仅对 C++). 默认情况下 不使用 探索法. 由于 探索法 只对 某些 输入文件 有效,
其他程序 的 编译速度 会变得 更慢.

第一次 编译器 必须 对 成员函数 (或对 成员数据 的 引用) 建立 一个 调用. 它 必须 (1) 判断出 这个类 是否 实现了 那个 名字 的
成员函数; (2) 决定调用 哪个 成员函数 (涉及到 推测 需要 做 哪种 类型转换); (3) 检查 成员函数对 调用者 是否 可见. 所有 这些 构成
更慢的 编译. 一般情形, 第二次 对 成员函数 (或对 成员数据 的 引用) 建立 的 调用, 必须再次 经过 相同 长度 的 处理. 这 意味着 象 这样的
代码

cout << "This " << p << " has " << n << "
legs.\n";

对 整个 三步骤 要做 六次 遍历. 通过 使用 软件缓存, ``命中'' 能够 显著地 减少 这种 代价. 然而 不幸的 是, 使用 这种 缓存
必须实现 其他 机制, 带来了 它 自己的 开销. `-fmemoize-lookups' 选项 打开 软件缓存.

因为 函数 的 正文环境 不同, 函数 对 成员 和 成员函数 的 访问权 (可见性) 也可能 不同, g++ 可能 需要 刷新 缓存.
使用 `-fmemoize-lookups' 选项, 每 编译完 一个 函数 就 刷新 缓存. 而 `-fsave-memoized' 选项 也
启用 同样的 缓存, 但是 当 编译器 发觉 最后 编译 的 函数的 正文环境 产生 的 访问权 和 下一个 待编译的 函数 相同, 编译器 就 保留缓存
内容. 这对 某个类 定义 许多 成员函数 时 非常 有用: 除了 某些 其他类 的 友函数, 每个 成员函数 拥有 和 其他 成员函数 完全一样 的 访问权,
因而 无需 刷新 缓存.

-fno-default-inline
默认为 不要 把 成员函数 内嵌, 因为 它们 定义在 类的 作用域 内 (仅C++).
-fno-defer-pop
一旦 函数 返回, 参数 就 立即 弹出. 对于 那些 调用 函数 后 必须 弹出 参数的 机器, 编译器 一般情况下 让 几次 函数调用 的 参数
堆积 在 栈 上, 然后 一次 全部 弹出.
-fforce-mem
做 数学运算 前 把 将要 使用的 内存操作数 送入 寄存器. 通过 把 内存访问转换成 潜在的 公共子表达式, 它 可能 产生 较好的 目标码. 如果
它们 不是公共子表达式, 指令组合 应该 消除 各自的 寄存器载荷. 我 乐意 倾听 不同意见.
-fforce-addr
做 数学运算 前 把 将要 使用的 内存地址常数 送入 寄存器. 它 可能 和 `-fforce-mem' 一样 产生 较好的 目标码.
我 乐意 倾听 不同意见.
-fomit-frame-pointer
对于 不需要 帧指针 (frame pointer) 的 函数, 不要 在 寄存器 中 保存 帧指针. 这样 能够 避免 保存, 设置 和 恢复 帧指针
的 指令; 同时 对 许多 函数 提供一个 额外的 寄存器. 但是 在 大多数 机器 上将 无法 调试.

某些机器上, 如 Vax, 这个 选项 无效, 因为 标准调用序列 自动 处理 帧指针, 通过 假装 不存在 而 不保存 任何 东西. 机器描述宏
FRAME_POINTER_REQUIRED 控制 目标机 是否 支持 这个选项.

-finline-functions
把 所有 简单的 函数 集成进 调用者. 编译器 探索式地 决定 哪些 函数 足够简单, 值得 这种 集成.

如果 集成了 所有 给定函数 的 调用, 而且 函数 声明为 static, 那么 一般说来 GCC 有权 不按 汇编代码 输出 函数.

-fcaller-saves
允许 在 寄存器 里 分配 数值, 但是 这个方案 通常 受到 各个 函数调用 的 冲击, 因此 GCC 生成 额外的 代码, 在 函数调用 的 前后
保存 和 复原 寄存器 内容. 仅当 生成代码 看上去 优于 反之结果 时 才 实现 这样 的 分配.

某些 机器 上 该选项 默认为 允许, 通常 这些 机器 没有 调用保护寄存器 代替 使用.

-fkeep-inline-functions
即使 集成了 某个 函数 的 所有 调用, 而且 该函数 声明为 static, 仍然 输出 这个函数 一个 独立的, 运行时 可调用 的
版本.
-fno-function-cse
不要 把 函数地址 存入 寄存器; 让 调用 固定函数 的 指令 显式 给出 函数地址.

这个选项 产生 效率 较低 的 目标码, 但是 如果 不用 这个选项, 某些 不寻常的 hack, 改变 汇编器 的 输出, 可能 因 优化 而 带来
困惑.

-fno-peephole
禁止 任何 机器相关的 peephole 优化.
-ffast-math
这个选项 出于 速度优化, 允许 GCC 违反 某些 ANSI 或 IEEE 规则/规格. 例如, 它 允许 编译器 假设 sqrt 函数
的 参数 是 非负数.

这个选项 不被 任何 `-O' 选项 打开, 因为 对于 严格 依靠 IEEE 或 ANSI 规则/规格 实现的 数学函数, 程序 可能
会产生 错误的 结果.

下列 选项 控制 特定的 优化. `-O2' 选项 打开 下面的 大多数 优化项, 除了 `-funroll-loops' 和
`-funroll-all-loops' 项.

而 `-O' 选项 通常 打开 `-fthread-jumps' 和 `-fdelayed-branch'
优化项, 但是 特定的 机器 上的 默认优化项 有可能 改变.

如果 特别情况 下 非常 需要 ``微调'' 优化, 你 可以 使用 下面的 选项.

-fstrength-reduce
执行 循环强度缩小 (loop strength reduction) 优化, 并且 消除 重复变量.
-fthread-jumps
执行 优化 的 地点 是, 如果 某个 跳转分支 的 目的地 存在 另一个 条件比较, 而且 该 条件比较 包含在 前一个 比较语句 之内, 那么 执行
优化. 根据 条件 是 true 或者 false, 前面 那条 分支 重定向 到 第二条 分支的 目的地 或者 紧跟在 第二条 分支 后面.
-funroll-loops
执行 循环展开 (loop unrolling) 优化. 仅对 循环次数 能够 在 编译时 或运行时 确定 的 循环 实行.
-funroll-all-loops
执行 循环展开 (loop unrolling) 优化. 对 所有 循环 实行. 通常 使 程序 运行的 更慢.
-fcse-follow-jumps
在 公共子表达式消元 (common subexpression elimination) 的 时候, 如果 没有 其他 路径 到达 某个 跳转 的
目的地, 就 扫过 这条 jump 指令. 例如, 如果 CSE 遇到 带有 else从句 的 if 语句, 当 条件测试 为
false 时, CSE 就 跟在 jump 后面.
-fcse-skip-blocks
它 类似于 `-fcse-follow-jumps' 选项, 但是 CSE 跟在 条件跳转 后面, 条件跳转 跳过了
语句块(block). 如果 CSE 遇到 一条 简单的 if 语句, 不带 else 从句,
`-fcse-skip-blocks' 选项 将导致 CSE 跟在 if 产生 的 跳转 后面.
-frerun-cse-after-loop
执行 循环优化 后, 重新 进行 公共子表达式消元.
-felide-constructors
如果 看上去 合理 就 省略 构造子 (仅C++). 根据 这个选项, 对于 下面的 代码, GNU C++ 直接 从 调用 foo
初始化 y, 而无需 通过 临时变量:

A foo (); A y = foo ();

如果 没有 这个选项, GNU C++ 首先 通过 调用 类型 A 合适的 构造子 初始化 y; 然后 把
foo 的 结果 赋给 临时变量; 最后, 用 临时变量 替换 `y' 的 初始值.

ANSI C++ 标准草案 规定了 默认行为 (`-fno-elide-constructors'). 如果 程序的 构造子 存在 副效应,
`-felide-constructors' 选项 能够 使 程序 有 不同的 表现, 因为 可能 忽略 一些 构造子 的 调用.

-fexpensive-optimizations
执行 一些 相对 开销 较大 的 次要 优化.
-fdelayed-branch
如果 对 目标机 支持 这个 功能, 它 试图 重新 排列 指令, 以便 利用延迟分支 (delayed branch) 指令 后面的 指令 空隙.
-fschedule-insns
如果 对 目标机 支持 这个 功能, 它 试图 重新 排列 指令, 以便 消除 因数据未绪 造成的 执行停顿. 这可以 帮助 浮点运算 或 内存访问
较慢 的 机器调取 指令, 允许 其他 指令 先执行, 直到 调取 指令 或 浮点运算 完成.
-fschedule-insns2
类似于 `-fschedule-insns' 选项, 但是 在 寄存器分配 完成后, 需要 一个 额外的 指令调度 过程. 对于 寄存器
数目 相对 较少, 而且 取内存指令 大于 一个周期 的 机器, 这个选项 特别 有用.

目标机选项 (TARGET OPTION)

缺省情况下, GNU CC 编译出 本机 类型 的 目标码. 然而 也可以 把他 安装成交叉编译器,
为 其他 机型 编译 程序. 事实上, 针对 不同的 目标机, 可以 同时 安装 GNU CC 相应 的 配置. 然后 用 `-b' 选项 指定
目标机种.

顺便提一下, 新版本 和 旧版本 的 GNU CC 可以 共存. 其中一个 版本 (可能是最新的 那个) 为 缺省 版本, 但是 有时候 你 希望 使用
其他 版本.

-b machine
参数 machine 指出 编译的 目标机种. 这个 选项 用于 安装为 交叉编译器 的 GNU CC.

参数 machine 的 值 和 配置 GNU CC 交叉编译器 时 设置 的 机器类型 一样. 例如, 如果 交叉编译器 配置有
`configure i386v', 意思是 编译 80386 上的 System V 目标码, 那么 你 可以 通过 `-b
i386v
' 运行 交叉编译器.

如果 没有 指定 `-b' 选项, 通常 指 编译 本机 目标码.

-V version
参数 version 指出 运行 哪个 版本 的 GNU CC. 这个 选项 用于 安装了 多个 版本 的 GCC. 例如, 如果
version 是 `2.0', 意味着 运行 GNU CC 2.0 版.

如果 没有 指定 `-V' 选项, 缺省版本 取决于 GNU CC 的 安装方式, 一般说来 推荐 使用 通用版本.

机器相关选项 (MACHINE DEPENDENT OPTION)

每一种 目标机型 都有 自己的 特别选项, 这些 选项 用 `-m
' 开关 引导, 选择 不同的 硬件 型号 或 配置 --- 例如, 68010 还是 68020, 有没有 浮点协处理器. 通过 指定 选项, 安装
编译器 的 一个 版本 能够 为 所有的型号 或 配置 进行 编译.

此外, 编译器 的 某些 配置 支持 附加的 特殊选项, 通常 是 为了 在 命令行 上兼容 这个 平台 的 其他 编译器.

下面是 针对 68000 系列 定义 的 `-m' 选项:

-m68000
-mc68000
输出 68000 的 目标码. 如果 编译器 按 基于 68000 的 系统 配置, 这个 选项 就是 缺省选项.
-m68020
-mc68020
输出 68020 的 目标码 (而不是 68000). 如果 编译器 按 基于 68020 的 系统 配置, 这个 选项 就是 缺省选项.
-m68881
输出 包含 68881 浮点指令 的 目标码. 对于 大多数 基于 68020 的 系统 这是 缺省选项, 除非 设置 编译器 时 指定了
-nfp .
-m68030
输出 68030 的 目标码. 如果 编译器 按 基于 68030 的 系统 配置, 这个 选项 就是 缺省选项.
-m68040
输出 68040 的 目标码. 如果 编译器 按 基于 68040 的 系统 配置, 这个 选项 就是 缺省选项.
-m68020-40
输出 68040 的 目标码, 但是 不使用 新指令. 生成 的 代码 可以 在 68020/68881 上, 也可以 在 68030 或 68040
上 较有效地 运行.
-mfpa
输出 包含 SUN FPA 浮点指令 的 目标码.
-msoft-float
输出 包含 浮点库调用 的 目标码. 警告: 所需的库 不是 GNU CC 的 组成部分. 一般说来 GCC 使用 该机型 本地 C
编译器 的相应部件, 但是 作 交叉编译 时 却不能 直接 使用. 你 必须 自己 管理 提供 合适的函数库 用于 交叉编译.
-mshort
认为 int 类型 是 16 位宽, 相当于 short int.
-mnobitfield
不使用 位域 (bit-field) 指令. `-m68000' 隐含指定了 `-mnobitfield'.
-mbitfield
使用 位域指令. `-m68020' 隐含指定了 `-mbitfield'. 如果 你 使用 未改装的 gcc, 这就是
默认选项.
-mrtd
采用 另一种 函数调用约定, 函数 接受 固定 数目的 参数, 用 rtd 指令 返回, 该指令 返回时 弹出 栈内的 参数. 这个 方法
能够 使 调用者节省 一条 指令, 因为 他 这里 不需要 弹出 参数.

这种 调用约定 不兼容 UNIX 的 正常 调用. 因此 如果 你 需要 调用 UNIX 编译器 编译的 库函数, 你 就不能 使用 这个选项.

此外, 所有 参数数量 可变地 函数 必须 提供 函数原型 (包括 printf); 否则 编译器 会生成 错误的 调用 代码.

另外, 如果 调用 函数 时 携带了 过多的 参数, 编译器 将 生成 严重错误的代码. (正常情况下, 多余的 参数 被 安全无害的 忽略.)

68010 和 68020 处理器 支持 rtd 指令, 但是 68000 不支持.

下面是 针对 VAX 定义 的 `-m' 选项:

-munix
禁止 输出 某些 跳转指令 (aobleq 等等), VAX 的 UNIX 汇编器 无法 跨越 长范围 (long ranges) 进行
处理.
-mgnu
如果 使用 GNU 汇编器, 则 输出 那些 跳转指令,
-mg
输出 g-format 浮点数, 取代 d-format.

下面是 SPARC 支持的 `-m' 选项开关:

-mfpu

-mhard-float
输出 包含 浮点指令 的 目标码. 这是 缺省选项.

-mno-fpu

-msoft-float
输出 包含 浮点库调用 的 目标码. 警告: 没有 为 SPARC 提供 GNU 浮点库. 一般说来 使用 该机型 本地 C 编译器
的相应部件, 但是 不能 直接 用于 交叉编译. 你 必须 自己 安排, 提供 用于交叉编译 的 库函数.

-msoft-float 改变了 输出文件 中的 调用约定; 因此 只有 用 这个 选项 编译 整个 程序 才有 意义.

-mno-epilogue

-mepilogue
使用 -mepilogue (缺省) 选项 时, 编译器 总是 把 函数 的 退出 代码 放在 函数 的 尾部. 任何 在 函数 中间 的
退出 语句 (例如 C 中的 return 语句) 将 产生出 跳转指令 指向 函数 尾部.

使用 -mno-epilogue 选项 时, 编译器 尽量 在 每个 函数 退出点 嵌入 退出 代码.

-mno-v8

-mv8
-msparclite
这三个 选项 选择 不同种类 的 SPARC 系统.

默认情况下 (除非 特别为 Fujitsu SPARClite 配置), GCC 生成 SPARC v7 目标码.

-mv8 生成 SPARC v8 目标码. 他 和 v7 目标码 唯一的 区别 是, 编译器 生成 整数乘法和 整数除法 指令, SPARC
v8 支持 该指令, 而 v7 体系 不支持.

-msparclite 生成 SPARClite 目标码. 增加了 SPARClite 支持的 整数乘法, 整数除法单步扫描
(integer divide step and scan (ffs)) 指令. v7 体系 不支持 这些 指令.

-mcypress

-msupersparc
这两个 选项 选择 处理器 型号, 针对 处理器 进行 代码 优化.

-mcypress 选项 (默认项) 使 编译器 对 Cypress CY7C602 芯片 优化 代码,
SparcStation/SparcServer 3xx 系列 使用 这种 芯片. 该选项 也 适用于 老式的 SparcStation 1, 2, IPX 等
机型..

-msupersparc 选项 使 编译器 对 SuperSparc 处理器 优化 代码, SparcStation 10, 1000 和
2000 系列 使用 这种 芯片. 同时 该选项 启用完整的 SPARC v8 指令集.

下面是 针对 Convex 定义 的 `-m' 选项:

-mc1
输出 C1 的 目标码. 当 编译器 对 C1 配置时, 这是 默认选项.
-mc2
输出 C2 的 目标码. 当 编译器 对 C2 配置时, 这是 默认选项.
-margcount
在 每个 参数列表 的 前面 放置 一个 参数计数字 (argument count word). 某些 不可移植 的 Convex 和 Vax 程序
需要 这个 参数计数字. (调试器 不需要 他, 除非 函数 带有 变长参数 列表; 这个 信息 存放在 符号表 中.)
-mnoargcount
忽略 参数计数字. 如果 你 使用 未改装 的 gcc, 这是 默认 选项.

下面是 针对 AMD Am29000 定义 的 `-m' 选项:

-mdw
生成的 目标码 认为 DW 置位, 就是说, 字节 和 半字 操作 由 硬件 直接 支持. 该选项 是 默认选项.
-mnodw
生成的 目标码 认为 DW 没有 置位.
-mbw
生成的 目标码 认为 系统 支持 字节 和 半字 写操作. 该选项 是 默认选项.
-mnbw
生成的 目标码 认为 系统 不支持 字节 和 半字 写操作. 该选项 隐含 开启 了 `-mnodw' 选项.
-msmall
使用 小内存模式, 小内存模式 假设 所有 函数 的 地址 位于 某个 256 KB 段内, 或者 所有 函数 的 绝对地址 小于 256K. 这样
就可以 用 call 指令 代替 const, consth, calli 指令 序列.
-mlarge
假设 不能 使用 call 指令; 这是 默认选项.
-m29050
输出 Am29050 的 目标码.
-m29000
输出 Am29000 的 目标码. 这是 默认选项.
-mkernel-registers
生成的 目标码 引用 gr64-gr95 寄存器 而不是 gr96-gr127 寄存器. 该选项 可以 用于 编译
内核代码, 内核 需要 一组 全局寄存器, 这些 全局寄存器 和 用户模式 使用的 寄存器 完全无关.

注意, 使用 这个 选项 时, `-f' 选项 中的 寄存器名字 必须是 normal, user-mode, names.

-muser-registers
使用 普通 全局寄存器集 gr96-gr127. 这是 默认选项.
-mstack-check
在 每次 堆栈 调整 后 插入 一条 __msp_check 调用. 这个选项 常用于 内核代码.

下面是 针对 Motorola 88K 体系 定义 的 `-m' 选项:

-m88000
生成的 目标码 可以 在 m88100 和 m88110 上 正常工作.
-m88100
生成的 目标码 在 m88100 上 工作的 最好, 但也可以 在 m88110 上 运行.
-m88110
生成的 目标码 在 m88110 上 工作的 最好, 可能 不能 在 m88100 上 运行.
-midentify-revision
在 汇编器 的 输出端 包含 一条 ident 指令, 记录 源文件名, 编译器名字 和 版本, 时标, 以及 使用的 编译选项,
-mno-underscores
在 汇编器 的 输出端, 符号名字 前面 不添加 下划线. 默认情况 是 在 每个名字 前面 增加 下划线 前缀.
-mno-check-zero-division
-mcheck-zero-division
早期 型号 的 88K 系统 在 除零操作 上 存在 问题, 特定情况下 许多 机器无法 自陷. 使用 这些 选项 可以 避免包含 (或 可以
显明包含) 附加的 代码, 这些代码 能够 检查 除零错, 发送 例外信号. GCC 所有 88K 的 配置 默认 使用
`-mcheck-zero-division' 选项.
-mocs-debug-info
-mno-ocs-debug-info
包含 (或忽略) 附加的 调试信息 (关于 每个 栈架结构 中 寄存器 的 使用), 88Open Object Compatibility
Standard, ``OCS'', 对 此信息 做了 说明. GDB 不需要 这些 额外信息. DG/UX, SVr4, 和 Delta 88 SVr3.2
的 默认配置 是 包含 调试信息, 其他 88k 机型 的 默认配置 是 忽略 这个信息.
-mocs-frame-position
-mno-ocs-frame-position
强制 (或 不要求) 把 寄存器值 存储到 栈架结构 中的 指定位置 (按 OCS 的说明). DG/UX, Delta88 SVr3.2 和 BCS
的 默认配置 使用 `-mocs-frame-position' 选项; 其他 88k 机型 的 默认配置 是
`-mno-ocs-frame-position'.
-moptimize-arg-area
-mno-optimize-arg-area
控制 如何 在 堆栈结构 中 存储 函数参数. `-moptimize-arg-area' 节省 空间, 但是 有可能 宕掉 某些 调试器
(不是 GDB). `-mno-optimize-arg-area' 证实 比 标准选项 好. 默认情况下 GCC 不优化 参数域.
-mshort-data-
num 通过 和 r0 关联, 产生 较小的 数据引用 (data reference), 这样 就可以 用 单指令调入
一个 数值 (而不是 平常的 双指令). 用户 通过 选项中的 num 控制 改变 哪种 数据引用. 例如, 如果 你 指定了
`-mshort-data-512', 那么 受影响的 数据引用 是 小于 512 字节 的 数据移动.
-mshort-data-num选项 对 大于 64K 的 num 无效.

-mserialize-volatile

-mno-serialize-volatile
产生, 或 不产生 代码 来保证 对 易变内存访问 的 结果一致.

对于 常用的 处理器 子型号, GNU CC 始终 默认 保证 这种 一致性. 如何实现 结果一致 取决于 处理器 子型号.

m88100 处理器 不对 内存引用 重新安排, 因此 访问结果 始终一致. 如果 使用了 `-m88100' 选项, GNU CC 不产生
任何 针对 结果一致 的 特别指令.

m88110 处理器 的 内存引用顺序 并不始终 符合 指令 请求的 引用顺序. 特别是 某条 读取指令 可能 在 先前的 存储指令 之前 执行.
多处理器 环境下, 乱序访问 扰乱了 易变内存访问 的 结果一致. 因此 当使用 `-m88000' 或 `-m88110'
选项时, GNU CC 在 适当的时候 产生 特别的指令 迫使 执行顺序 正确.

这些 用于 保证 一致性 的 额外代码 有可能 影响 程序 的 性能. 如果 你 确认能够 安全地 放弃 这种 保证, 你 可以 使用
`-mno-serialize-volatile' 选项.

如果 你 使用 `-m88100' 选项, 但是 需要 在 m88110 处理器 上 运行时 的 结果一致, 你 应该 加上
`-mserialize-volatile' 选项.

-msvr4

-msvr3
打开 (`-msvr4') 或 关闭 (`-msvr3') 和 System V 第四版 (SVr4) 相关的 编译器扩展.
效果 如下:
   *
输出 哪种 汇编语法 (你 可以 使用 `-mversion-03.00' 选项 单独 选择).
   *
`-msvr4' 使 C 预处理器 识别 `#pragma weak' 指令
   *
`-msvr4' 使 GCC 输出 额外的 声明指令(declaration directive), 用于 SVr4.

除了 SVr4 配置, `-msvr3' 是 所有 m88K 配置 的 默认选项.

-mtrap-large-shift
-mhandle-large-shift
包含 一些 指令, 用于 检测 大于 31 位 的 位移 (bit-shift); 根据 相应的 选项, 对 这样 的 位移 发出 自陷 (trap)
或 执行 适当 的 处理代码. 默认情况下, GCC 对 大位移 不做 特别处理.
-muse-div-instruction
很早以前 的 88K 型号 没有 (div) 除法指令, 因此 默认情况下 GCC 避免 产生这条 指令. 而 这个 选项 告诉 GCC 该指令 是
安全的.
-mversion-03.00
在 DG/UX 配置 中 存在 两种 风格 的 SVr4. 这个选项 修改 -msvr4 , 选择 hybrid-COFF 或
real-ELF 风格. 其他 配置 均 忽略 该选项.
-mwarn-passed-structs
如果 某个函数 把 结构 当做 参数 或 结果 传递, GCC 发出 警告. 随着 C 语言 的 发展, 人们 已经 改变了 传递 结构 的 约定, 它
往往 导致移植问题. 默认情况下, GCC 不会 发出 警告.

下面的选项 用于 IBM RS6000:

-mfp-in-toc

-mno-fp-in-toc
控制 是否 把 浮点常量 放到 内容表 (TOC) 中, 内容表 存放 所有的 全局变量和 函数地址. 默认情况下, GCC 把 浮点常量 放到 这里;
如果 TOC 溢出, `-mno-fp-in-toc' 选项 能够 减少 TOC 的 大小, 这样 就可以 避免 溢出.

下面的 `-m' 选项 用于 IBM RT PC:

-min-line-mul
对于 整数乘法 使用 嵌入代码. 这是 默认选项.
-mcall-lib-mul
对于 整数乘法 使用 lmul$$ .
-mfull-fp-blocks
生成 全尺寸 浮点数据块, 包括 IBM 建议 的 最少数量 的 活动空间 (scratch space). 这是 默认选项.
-mminimum-fp-blocks
不要 在 浮点数据块 中 包括 额外的 活动空间. 这样 就 产生 较小 但是 略慢的 可执行程序, 因为 活动空间 必须 动态分配.
-mfp-arg-in-fpregs
采用 不兼容 IBM 调用约定 的 调用序列, 通过 浮点寄存器 传送 浮点参数. 注意, 如果 指定了 这个选项, varargs.h
stdargs.h 将 无法 支持 浮点单元.
-mfp-arg-in-gregs
使用 正常的 调用约定 处理 浮点参数. 这是 默认选项.
-mhc-struct-return
通过 内存 返回 大于 一个字 的 结构, 而不是 通过 寄存器. 用于 兼容 MetaWare HighC (hc) 编译器. 使用
`-fpcc-struct-return' 选项 可以 兼容 Portable C 编译器 (pcc).
-mnohc-struct-return
如果可以, 通过 寄存器 返回 某些 大于 一个字 的 结构. 这是 默认选项. 如果 打算 兼容 IBM 提供 的 编译器, 请使用
`-fpcc-struct-return' 或 `-mhc-struct-return' 选项.

下面的 `-m' 选项 用于 MIPS 家族 的 计算机:

-mcpu=cpu-type
生成 指令 的 时候, 假设 默认的 机器类型 是 cpu-type . 默认情况下 的 cpu-type
default, GCC 将选取 任何机型 上 都是 最长周期时间 的 指令, 这样 才能使 代码在 所有的 MIPS 处理器 上 以 合理 的
速度 运行. cpu-type 的 其他 选择 是 r2000, r3000, r4000, 和
r6000. 虽然 选定 某个 cpu-type 后, GCC 将 针对 选定的 芯片 安排 对应的 工作, 但是 如果
不指定�1�7 -mips2-mips3 选项, 编译器 不会 输出 任何 不符合 MIPS ISA (instruction
set architecture) 一级 的 代码.
-mips2
输出 MIPS ISA 二级指令 (可能的扩展, 如平方根指令). -mcpu=r4000-mcpu=r6000 选项
必须 和 -mips2 联用.
-mips3
输出 MIPS ISA 三级指令 (64位指令). -mcpu=r4000 选项 必须 和 -mips2 联用. (译注:
疑为 -mips3)
-mint64
-mlong64
-mlonglong128
这些 选项 目前 不起作用.
-mmips-as
产生 用于 MIPS 汇编器 的 代码, 同时 使用 mips-tfile 添加 普通的 调试信息. 对于 大多数 平台 这是 默认选项,
除了 OSF/1 参考平台, 它 使用 OSF/rose 目标 格式. 如果 打开了 任一个 -ggdb, -gstabs, 或
-gstabs+ 选项开关, mips-tfile 程序 就把 stab 封装在 MIPS ECOFF 里面.
-mgas
产生 用于 GNU 汇编器 的 代码. 在 OSF/1 参考平台 上 这是 默认选项, 它 使用 OSF/rose 目标 格式.
-mrnames
-mno-rnames
-mrnames 开关选项 告诉 输出代码 使用 MIPS 软件名称 说明 寄存器, 而不是 硬件名称 (就是说, 用 a0
代替 $4). GNU 汇编器 不支持 -mrnames 选项, 而 MIPS 汇编器 则 运行 MIPS C 预处理器 处理
源文件. -mno-rnames 是 默认选项.
-mgpopt
-mno-gpopt
-mgpopt 开关选项 要求 在 正文段 中 把 所有的 数据声明 写到 指令 前面, 使 各种 MIPS 汇编器 对 短类型 全局 或
静态 数据项 (short global or static data items) 输出 单字内存访问 而不是 双字内存访问. 当 打开 编译优化 时, 这是
默认功能.
-mstats
-mno-stats
每次 处理完 非嵌入函数 (non-inline function) 后, -mstats 开关选项 使 编译器 向 标准错误文件 输出
一行 关于 程序 的 统计资料 (保存的 寄存器 数目, 堆栈 大小, 等等).
-mmemcpy
-mno-memcpy
-mmemcpy 开关选项 使 所有 的 块移动 操作 调用 适当的 string 函数 (memcpy
bcopy), 而不是 生成 嵌入代码.
-mmips-tfile
-mno-mips-tfile
当 MIPS 汇编器 生成 mips-tfile 文件 (用于 帮助 调试) 后, -mno-mips-tfile 开关选项
阻止 编译器 使用 mips-tfile 后期处理 (postprocess) 目标文件. 不运行 mips-tfile 就 没有
调试器 关注的 局部变量. 另外, stage2stage3 目标文件 将把 临时文件名 传递给 汇编器, 嵌在 目标文件
中, 这 意味着不比较 目标文件 是否 相同.
-msoft-float
输出 包含 浮点库调用. 警告: 所需库 不是 GNU CC 的 一部分. 一般说来 使用 该机型 本地 C 编译器 的相应部件, 但是
不能 直接 用于 交叉编译, 你 必须 自己 安排, 提供交叉编译 适用的 库函数.
-mhard-float
输出 包含 浮点指令. 如果 编译器 没有 被改动, 这就是 默认选项.
-mfp64
编译器 认为 状态字 的 FR 置位(on), 也就是说 存在 32 64-bit 浮点寄存器, 而不是 32 32-bit 浮点寄存器.
同时 必须 打开 -mcpu=r4000-mips3 开关.
-mfp32
认为 存在 32 32-bit 浮点寄存器. 这是 默认选项.

-mabicalls

-mno-abicalls
输出 (或 不输出) .abicalls, .cpload, 和 .cprestore 伪指令, 某些
System V.4 版本 用于 位置无关代码.
-mhalf-pic
-mno-half-pic
-mhalf-pic 开关选项 要求 把 外部引用 的 指针 放到 数据段, 并且 载入 内存, 而不放到正文段. 该选项 目前
不起作用.
-G num
把 小于等于 num 字节 的 全局 或 静态 数据 放到 小的 数据段 或 bss 段, 而不是普通的 数据段 或 bss 段. 这样
汇编器 可以 输出 基于 全局指针 (gp$28), 的 单字内存访问指令 而非 普通的 双字指令. 默认情况下, 用
MIPS 汇编器 时 num 是 8, 而 GNU 汇编器 则为 0. 另外, -Gnum 选项 也被 传递 给
汇编器 和 连接器. 所有 的 模块 必须在 相同的 -Gnum 值下 编译.
-nocpp
汇编 用户汇编文件 (带有 `.s' 后缀) 时, 告诉 MIPS 汇编器 不要 运行 预处理器.

下面的 `-m' 选项 用于 Intel 80386 族 计算机: -m486

-mno-486
控制 是否 生成 对 486 优化 的 代码.
-msoft-float
输出 包含 浮点库调用. 警告: 所需库 不是 GNU CC 的 一部分. 一般说来 使用 该机型 本地 C 编译器 的相应部件, 但是
不能 直接 用于 交叉编译, 你 必须 自己 安排, 提供 交叉编译 适用的 库函数.

在 函数 把 浮点返回值 放在 80387 寄存器栈 的 机器 上, 即使 设置了 `-msoft-float' 选项, 也可能会 发出
一些 浮点操作码.

-mno-fp-ret-in-387
不用 FPU 寄存器 返回 函数值.

通常 函数调用约定 把 floatdouble 的 返回值 放在 FPU 寄存器 中, 即使 不存在 FPU. 这种作法
的 理念是 操作系统 应该 仿真出 FPU.

而 `-mno-fp-ret-in-387' 选项 使 浮点值 通过 普通的 CPU 寄存器 返回.

下面的 `-m' 选项 用于 HPPA 族 计算机:

-mpa-risc-1-0
生成 PA 1.0 处理器 的 目标码.
-mpa-risc-1-1
生成 PA 1.1 处理器 的 目标码.
-mkernel
生成 适用于 内核 的 目标码. 特别要 避免 add 指令, 它 有 一个 参数 是 DP 寄存器; 用 addil 代替
add指令. 这样 可以 避免 HP-UX 连接器 的 某个 严重 bug.
-mshared-libs
生成 能够 连接 HP-UX 共享库 的 目标码. 该选项 还没有 实现 全部功能, 对 PA 目标 默认为 关闭. 使用 这个选项 会 导致 编译器
生成 错误的 目标码.
-mno-shared-libs
不生成 连接 HP-UX 共享库 的 目标码. 这是 PA 目标 的 默认选项.
-mlong-calls
生成的 目标码 允许 同一个 源文件 中的 函数调用, 调用点 和 被调函数的 距离 可以 超过 256K 之远. 不需要 打开 这个 开关选项, 除非
连接器给出 ``branch out of range errors`` 这样的 错误.
-mdisable-fpregs
防止 任何情况下 使用 浮点寄存器. 编译 内核 需要 这个选项, 内核 切换浮点寄存器 的 执行环境 速度 非常缓慢. 如果 打开了 这个 开关选项
同时试图 浮点操作, 编译 将 失败.
-mdisable-indexing
防止 编译器 使用 索引地址模式 (indexing address mode). 这样 在 MACH 上 编译 MIG 生成的 代码 时, 可以 避免
一些 非常 晦涩的 问题.
-mtrailing-colon
在 标记定义 (label definition) 的 末尾 添加 一个 冒号 (用于 ELF 汇编器).

下面的 `-m' 选项 用于 Intel 80960 族 计算机:

-mcpu-type
默认 机器 类型 为 cpu-type , 使 编译器 产生 对应的 指令, 地址模式 和 内存对齐. 默认的
cpu-typekb; 其他 选择 有 ka, mc, ca, cf,
sa, 和 sb.
-mnumerics
-msoft-float
-mnumerics 开关选项 指出 处理器 不支持 浮点指令. -msoft-float 开关选项 指出 不应该 认为
机器 支持 浮点操作.
-mleaf-procedures
-mno-leaf-procedures
企图 (或防止) 改变 叶过程 (leaf procedure), 使其 可被 bal 指令 以及 call 指令 调用.
对于 直接函数调用, 如果 bal 指令 能够 被 汇编器 或 连接器 替换, 这 可以 产生 更有效 的 代码, 但是 其他 情况下 产生
较低效 的 代码, 例如 通过 函数指针 调用 函数, 或 使用了 不支持 这种 优化 的 连接器.
-mtail-call
-mno-tail-call
执行 (或不执行) 更多的 尝试 (除过 编译器 那些 机器无关 部分), 优化进入 分支 的 尾递归 (tail-recursive) 调用. 你
可能 不需要 这个, 因为 检测 什么 地方 无效 没有 全部 完成. 默认 开关 是 -mno-tail-call.
-mcomplex-addr
-mno-complex-addr
认为 (或 不认为) 在 当前的 i960 设备 上, 值得 使用 复合地址模式 (complex addressing mode). 复合地址模式
可能 不值得 用到 K 系列, 但是一定 值得 用在 C 系列. 目前 除了 CB 和 CC 处理器, 其他 处理器 上
-mcomplex-addr 是 默认选项.
-mcode-align
-mno-code-align
把 目标码 对齐到 8 字节 边界 上 (或者 不必), 这样 读取 会 快一些. 目前 只对 C 系列 默认 打开.
-mic-compat
-mic2.0-compat
-mic3.0-compat
兼容 iC960 v2.0 或 v3.0.
-masm-compat
-mintel-asm
兼容 iC960 汇编器.
-mstrict-align
-mno-strict-align
不允许 (或允许) 边界不对齐 的 访问.
-mold-align
使 结构对齐 (structure-alignment) 兼容 Intel 的 gcc 发行版本 1.3 (基于 gcc 1.37). 目前 这个选项
有点问题, 因为 #pragma align 1 总是 作 同样的 设定, 而且 无法 关掉.

下面的 `-m' 选项 用于 DEC Alpha 设备:

-mno-soft-float
-msoft-float
使用 (或 不使用) 硬件浮点指令 进行 浮点运算. 打开 -msoft-float 时, 将 使用 `libgcc1.c'
中的 函数 执行 浮点运算. 除非 它们 被 仿真 浮点操作 的 例程 替换, 或者 类似, 它们 被 编译为 调用 仿真例程, 这些 例程 将发出 浮点操作.
如果 你 为 不带 浮点操作 的 Alpha 编译 程序, 你 必须 确保 建立了 这个 库, 以便 不调用 仿真例程.

注意, 不带 浮点操作 的 Alpha 也要求 拥有 浮点寄存器.

-mfp-reg
-mno-fp-regs
生成 使用 (或 不使用) 浮点寄存器群 的 目标代码. -mno-fp-regs 包含有 -msoft-float
开关选项. 如果 不使用 浮点寄存器, 浮点操作数 就象 整数 一样 通过整数寄存器 传送, 浮点运算结果 放到 $0 而不是 $f0. 这是 非标准 调用,
因此 任何 带有 浮点 参数或返回值 的 函数, 如果 被 -mno-fp-regs 开关 编译过的 目标码 调用, 它 也必须 用这个 选项
编译.

这个选项 的 典型用法 是 建立 内核, 内核 不使用 任何 浮点寄存器, 因此 没必要 保存 和 恢复 这些 寄存器.

下面 附加的 选项 出现在 System V 第四版 中, 用于 兼容 这些 系统 中的其他 编译器:

-G
在 SVr4 系统 中, gcc 出于 兼容 接受了 `-G' 选项 (然后 传递给 连接器). 可是 我们 建议 使用
`-symbolic' 或 `-shared'选项, 而不在 gcc 命令行 上 出现 连接选项.
-Qy
验证 编译器 用的 工具 的 版本, 输出到 .ident 汇编指令.
-Qn
制止 输出端 的 .ident 指令 (默认选项).
-YP,dirs
对于 `-l' 指定的 库文件, 只搜索 dirs. 你 可以 在 dirs 中 用 冒号 隔开 各个
目录项.
-Ym,dir
dir 目录 中 寻找 M4 预处理器. 汇编器 使用 这个 选项.

代码生成选项 (CODE GENERATION OPTION)

下面的 选项 和 平台 无关, 用于 控制 目标码生成 的 接口约定.

大部分 选项 以 `-f' 开始. 这些选项 拥有 确定 和 否定 两种 格式; `-ffoo' 的 否定格式 是
`-fno-foo'. 后面的 描述 将 只列举 其中 的 一个 格式 --- 非默认 的 格式. 你 可以 通过 添加或去掉
`no-' 推测出 另一个 格式.

-fnonnull-objects
假设 通过 引用 (reference) 取得的 对象 不为 null (仅 C++).

一般说来, GNU C++ 对 通过 引用 取得的 对象 作 保守 假设. 例如, 编译器 一定会 检查 下似 代码 中的 a 不为
null:

obj &a = g (); a.f (2);

检查 类似 的 引用 需要 额外的 代码, 然而 对于 很多 程序 是 不必要的. 如果 你的 程序 不要求 这种检查, 你 可以 用
`-fnonnull-objects' 选项 忽略它.

-fpcc-struct-return
函数 返回 structunion 值时, 采用 和 本地编译器 相同的 参数约定. 对于 较小的结构, 这种约定的
效率 偏低, 而且 很多 机器 上 不能 重入; 它的 优点 是 允许 GCC 编译的 目标码 和 PCC 编译 的 目标码 互相调用.
-freg-struct-return
一有可能 就 通过 寄存器 返回 structunion 函数值. 对于 较小的结构, 它 比
-fpcc-struct-return 更有效率.

如果 既没有 指定 -fpcc-struct-return , 也没有 指定 -freg-struct-return, GNU
CC 默认使用 目标机 的 标准约定. 如果 没有 标准约定, GNU CC 默认采用 -fpcc-struct-return.

-fshort-enums
enum 类型 只分配 它 声明的 值域范围 的 字节数. 就是说, enum 类型 等于 大小足够 的 最小整数类型.
-fshort-double
使 double 类型 的 大小 和 float 一样.
-fshared-data
要求 编译结果 的 数据 和 非 const 变量 是 共享数据, 而不是 私有数据. 这种差别 仅在 某些 操作系统 上面 有意义,
那里的 共享数据 在 同一个程序 的 若干 进程 间 共享, 而 私有数据 在 每个 进程 内 都有 副件.
-fno-common
即使 未初始化 的 全局变量 也 分配在 目标文件 的 bss 段, 而不是 把 它们当做 普通块 (common block) 建立. 这样的 结果
是, 如果 在 两个 不同 的 编译结果 中 声明了 同一个 变量 (没使用 extern ), 连接 它们 时 会 产生 错误. 这个选项 可能
有用 的 唯一情况 是, 你 希望 确认 程序 能 在 其他系统 上 运行, 而 其他系统 总是 这么 做.
-fno-ident
忽略 `#ident' 指令.
-fno-gnu-linker
不要 把 全局初始化部件 (如 C++ 的 构造子 和 解构子) 输出为 GNU 连接器使用 的 格式 (在 GNU 连接器 是 标准方法 的 系统
上). 当你 打算 使用 非 GNU 连接器 的 时候 可以用 这个选项, 非GNU连接器 也需要 collect2 程序 确保 系统连接器 放入
构造子 (constructor) 和 解构子 (destructor). (GNU CC 的 发布包 中 包含有 collect2 程序.)
对于 必须 使用 collect2 的 系统, 编译器驱动程序 gcc 自动 配置为 这么做.
-finhibit-size-directive
不要 输出 .size 汇编指令, 或其他 类似指令, 当 某个函数 一分为二, 两部分 在 内存 中距离 很远 时 会 引起 问题. 当
编译 `crtstuff.c' 时 需要 这个选项; 其他情况下 都不应该 使用.
-fverbose-asm
输出 汇编代码 时 放些 额外的 注释信息. 这个选项 仅用于 确实 需要阅读 汇编输出 的 时候 (可能 调试 编译器 自己 的 时候).
-fvolatile
使 编译器 认为 所有 通过 指针 访问 的 内存 是 易变内存 (volatile).
-fvolatile-global
使 编译器 认为 所有的 外部和全局变量 是 易变内存.
-fpic
如果 支持 这种 目标机, 编译器 就生成 位置无关目标码. 适用于 共享库 (shared library).
-fPIC
如果 支持 这种 目标机, 编译器 就输出 位置无关目标码. 适用于 动态连接 (dynamic linking), 即使 分支 需要 大范围 转移.
-ffixed-reg
把 名为 reg 的 寄存器 按 固定寄存器 看待 (fixed register); 生成的 目标码不应该 引用 它 (除了 或许 用作
栈指针, 帧指针, 或其他 固定的角色).

reg 必须是 寄存器 的 名字. 寄存器 名字 取决于 机器, 用 机器描述宏文件 的 REGISTER_NAMES
定义.

这个选项 没有 否定格式, 因为 它 列出 三路选择.

-fcall-used-reg
把 名为 reg 的 寄存器 按 可分配寄存器 看待, 不能 在 函数调用 间 使用. 可以 临时使用 或 当做 变量 使用, 生存期
不超过 一个 函数. 这样编译的 函数 无需 保存 和 恢复 reg 寄存器.

如果 在 可执行模块 中, 把 这个选项 说明的 寄存器 用作 固定角色 将会产生 灾难性结果, 如 栈指针 或 帧指针.

这个选项 没有 否定格式, 因为 它 列出 三路选择.

-fcall-saved-reg
把 名为 reg 的 寄存器 按 函数 保护 的 可分配寄存器 看待. 可以 临时使用 或 当做 变量使用, 它 甚至能 在 函数 间
生存. 这样编译的 函数 会 保存 和 恢复 使用中 的 reg 寄存器.

如果 在 可执行模块 中, 把 这个选项 说明的 寄存器 用作 固定角色 将会产生 灾难性结果, 如 栈指针 或 帧指针.

另一种 灾难 是 用 这个选项 说明的 寄存器 返回 函数值.

这个选项 没有 否定格式, 因为 它 列出 三路选择.

PRAGMAS

GNU C++ 支持 两条 `#pragma' 指令 使 同一个 头文件 有 两个用途: 对象类 的 接口定义,
对象类 完整的内容定义.

#pragma interface
(仅对 C++) 在 定义 对象类 的 头文件 中, 使用 这个指令 可以 节省 大部分采用 该类 的 目标文件 的 大小. 一般说来, 某些信息
(内嵌成员函数 的 备份副件, 调试信息, 实现 虚函数 的 内部表格等) 的 本地副件 必须 保存在 包含 类定义 的 各个 目标文件 中. 使用 这个
pragma 指令 能够 避免 这样的 复制. 当 编译 中 引用 包含 `#pragma interface' 指令 的 头文件 时, 就 不会
产生 这些 辅助信息 (除非 输入的 主文件 使用了 `#pragma implementation'指令). 作为替代, 目标文件 将包含 可被
连接时 解析的 引用 (reference).
#pragma implementation
#pragma implementation "objects.h"
(仅对 C++) 如果 要求 从 头文件 产生 完整的 输出 (并且 全局可见), 你 应该 在 主输入文件 中 使用 这条 pragma. 头文件 中
应该 依次 使用 `#pragma interface' 指令. 在 implementation 文件 中 将 产生 全部 内嵌成员函数 的
备份, 调试信息, 实现 虚函数 的 内部表格等.

如果 `#pragma implementation' 不带 参数, 它 指的是 和 源文件 有 相同基本名 的 包含文件; 例如,
`allclass.cc' 中, `#pragma implementation' 等于 `#pragma
implementation allclass.h
'. 如果 某个 implementation 文件 需要 从 多个 头文件 引入 代码, 就应该
使用 这个 字符串参数.

不可能 把 一个头文件 里面 的 内容 分割到 多个 implementation 文件 中.

文件 (FILE)

file.c             C 源文件
file.h C 头文件 (预处理文件)
file.i 预处理后 的 C 源文件
file.C C++ 源文件
file.cc C++ 源文件
file.cxx C++ 源文件
file.m Objective-C 源文件
file.s 汇编语言文件
file.o 目标文件
a.out 连接的输出文件
TMPDIR/cc* 临时文件
LIBDIR/cpp 预处理器
LIBDIR/cc1 C 编译器
LIBDIR/cc1plus C++ 编译器
LIBDIR/collect 某些机器需要的连接器前端(front end)程序
LIBDIR/libgcc.a GCC 子例程 (subroutine) 库
/lib/crt[01n].o 启动例程 (start-up)
LIBDIR/ccrt0 C++ 的附加启动例程
/lib/libc.a 标准 C 库, 另见 intro (3)
/usr/include #include 文件的标准目录
LIBDIR/include #include 文件的标准 gcc 目录
LIBDIR/g++-include #include 文件的附加 g++ 目录

LIBDIR 通常为 /usr/local/lib/machine/version.
TMPDIR 来自 环境变量 TMPDIR (如果 存在, 缺省为 /usr/tmp , 否则为
/tmp).