GCC 中文手册(中)

                                    GCC 中文手册(中)



-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

-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'选项打开,因为对于严格依靠IEEEANSI规则/规格实现的数学函数,程序可能 会产生错误的结果.

下列选项控制特定的优化. `-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);否则编译器会生成错误的调用代码.

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

6801068020处理器支持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'选项.

(待续)

你可能感兴趣的:(GNU/Linux程序设计)