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-clash -Werror -Wformat -Wid-clash- 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 -d letters -fpretend-float -g -g level -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)
-A assertion -C -dD -dM -dN -D macro[= defn] -E -H -idirafter dir -include file -imacros file -iprefix file -iwithprefix dir -M -MD -MM -MMD -nostdinc -P -U macro -undef
汇编器选项 (Assembler Option)
-Wa, option
连接器选项 (Linker Option)
-l library -nostartfiles -nostdlib -static -shared -symbolic -Xlinker  option -Wl, option -u symbol
目录选项 (Directory Option)
-B prefix -I dir -I- -L dir
目标机选项 (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, inlinetypeof 关键字, 以及 诸如 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 中 的 宏定义 生效, 可以 用于 其他 输入文件. 在 处理 ` -imacros file' 选项 之前, 预处理器 首先 处理 ` -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 显示 引用过的 头文件 名.

 

-A question ( answer )
如果 预处理器 做 条件测试, 如 ` #if # question ( answer )', 该选项 可以 断言 (Assert) question 的 答案 是 answer. -A-' 关闭 一般用于 描述 目标机 的 标准 断言.

 

-D macro
定义 宏 macro, 宏 的 内容 定义为 字符串 ` 1'.

 

-D macro = defn
定义 宏 macro 的 内容 为 defn. 命令行 上 所有的 ` -D' 选项 在 ` -U' 选项 之前 处理.

 

-U macro
取消 宏 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 执行 连接 操作, 这些 目标文件 将 成为连接器 的 输入文件.

 

-l library
连接 名为 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)

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

-I dir
在 头文件 的 搜索路径 列表 中 添加 dir 目录.

 

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

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

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

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

 

-L dir
在 ` -l' 选项 的 搜索路径 列表 中 添加 dir 目录.

 

-B prefix
这个选项 指出 在何处 寻找 可执行文件, 库文件, 以及 编译器 自己 的 数据文件.

编译器 驱动程序 需要 执行 某些 下面的 子程序: `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-clash- 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-clash
对于 不同 枚举类型 之间 的 转换 发出 警告 (仅适用于 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

-gdwarf level
请求 生成 调试信息, 同时 用 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__' 导致 在 跟踪 中 包括 返回指令.

 

-d letters
编译 的 时候, 在 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.hstdargs.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-typedefault, 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 函数 ( memcpybcopy), 而不是 生成 嵌入代码.

 

-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. 另外, -G num 选项 也被 传递 给 汇编器 和 连接器. 所有 的 模块 必须在 相同的 -G num 值下 编译.

 

-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 族 计算机:

-m cpu-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). 

转载于:https://www.cnblogs.com/fanweisheng/p/11082447.html

你可能感兴趣的:(c/c++,操作系统,ux)