跳过导航链接 | |
退出打印视图 | |
![]() |
Oracle Solaris Studio 12.3:C++ 用户指南 Oracle Solaris Studio 12.3 Information Library (简体中文) |
A.2.18 -filt[= filter[,filter...]]
A.2.75 -Qoption phase option[,option...]
A.2.80 -Rpathname[ :pathname...]
A.2.88 -traceback[={ %none|common|signals_list}]
A.2.101.2 -xalias_level=simple
A.2.101.3 -xalias_level=compatible
A.2.105.1 用于 SPARC 和 x86 的 -xarch 标志
A.2.105.2 用于 SPARC 的 -xarch 标志
A.2.107 -xbinopt={prepare| off}
A.2.108 -xbuiltin[={ %all|%default|%none}]
A.2.114 -xdebugformat=[stabs|dwarf]
A.2.116 -xdumpmacros[= value[,value...]]
A.2.122 -xinline[= func-spec[,func-spec...]]
A.2.123 -xinstrument=[ no%]datarace
A.2.128 -xkeepframe[=[ %all,%none,name,no% name]]
A.2.129 -xlang=language [,language]
A.2.161 -xprefetch[= a[,a...]]
A.2.162 -xprefetch_auto_type= a
A.2.165 -xprofile_ircache[ =path]
A.2.176 -xtrigraphs[={ yes|no}]
本节按字母顺序列出所有的 C++ 编译器选项,并指出所有的平台限制。
按照调用每个组件时的方式显示该组件,但不实际执行该组件。还显示命令选项扩展的过程。
指定 链接的库绑定是symbolic、dynamic(共享)还是 static(非共享)。
可以在命令行上多次使用 –B 选项。该选项传递给链接程序 ld。
注 - 在 Oracle Solaris 64 位编译环境中,许多系统库只能用作动态库。因此,请勿在命令行上将 -Bstatic 用作最后一个切换开关。
binding 必须是下表中列出的值之一:
|
(–B 和 binding 值之间不能有空格。)
如果没有指定 -B,则使用 –Bdynamic。
要静态链接 C++ 缺省库,请使用 –staticlib 选项。
-Bstatic 和 -Bdynamic 选项会影响缺省情况下提供的库的链接。为了确保动态链接缺省库,最后使用的 –B 应该是 –Bdynamic。
在 64 位环境中,许多系统库只能用作共享动态库。其中包括 libm.so 和 libc.so(不提供 libm.a 和 libc.a)。因此,在 64 位 Oracle Solaris 操作系统环境中,-Bstatic 和 -dn 可能会导致产生链接错误。这些情况下应用程序必须与动态库链接。
以下编译器命令链接 libfoo.a,即使 libfoo.so 存在也是如此,所有其他库都是动态链接的:
example% CC a.o –Bstatic –lfoo –Bdynamic
对于包含 C++ 代码的程序,切勿使用 -Bsymbolic,而应使用链接程序映射文件。
如果使用 -Bsymbolic,不同模块中的引用会绑定到应是一个全局对象内容的不同副本。
异常机制依赖对地址的比较。如果您具有某项内容的两个副本,它们的地址就不等同且异常机制可能失败,这是由于异常机制依赖对假设为唯一地址内容的比较。
如果在不同的步骤中进行编译和链接,并要使用 -Bbinding 选项,就必须在链接步骤中包括该选项。
–nolib、–staticlib、ld(1) 手册页以及11.5 静态链接标准库和《链接程序和库指南》
该选项指示 CC 驱动程序抑制通过 ld 进行链接,并为每个源文件生成一个 .o 文件。如果只在命令行上指定一个源文件,就可以用 -o 选项显式指定目标文件。
如果输入 CC -c x.cc,则会生成 x.o 目标文件。
如果输入 CC -c x.cc -o y.o,则会生成 y.o 目标文件。
当编译器为输入文件 (.c、.i) 生成目标代码时,编译器总是在工作目录下生成 .o 文件。如果抑制链接步骤,则不会删除 .o 文件。
–o filename 和 –xe
(SPARC) 已废弃,请勿使用此选项。当前的 Oracle Solaris 操作系统软件不再支持 SPARC V7 体系结构。使用此选项编译生成的代码在当前的 SPARC 平台中运行较慢。应改用 -xO,并利用 -xarch、-xchip 和 -xcache 编译器缺省值。
设置编译器的主要发行版兼容模式。该选项控制 __SUNPRO_CC_COMPAT 预处理程序宏。
C++ 编译器有两种主要模式。-compat=5(缺省模式)接受符合 2003 年更新的 ANSI/ISO 1998 C++ 标准的构造,并且在 -compat=5 模式下将生成与 C++ 5.0 到 5.12 兼容的代码。在 Oracle Solaris x86 和 Linux 平台上,-compat=g 选项可以添加与 gcc/g++ 编译器的源和二进制兼容性。由于在名称改编、类布局、虚拟表布局和其他 ABI 详细信息方面有不兼容的重大更改,因此这些模式互不兼容。
在以前发行版中接受由 4.2 编译器定义的语义和语言的 兼容性模式 (-compat=4) 不再可用。
这些模式由 –compat 选项进行区分,如以下部分中所示。
-compat 选项可以使用下表中显示的值。
|
使用 -compat=g 时,二进制兼容性仅扩展到共享(动态或 .so)库,而不扩展到个别 .o 文件或归档 (.a) 库。
以下示例显示了将 g++ 共享库链接到 C++ 主程序的过程:
% g++ -shared -o libfoo.so -fpic a.cc b.cc c.cc % CC -compat=g main.cc -L. -lfoo
以下示例显示了将 C++ 共享库链接到 g++ 主程序的过程:
% CC -compat=g -G -o libfoo.so -Kpic a.cc b.cc c.cc % g++ main.cc -L. -lfoo
如果没有指定 –compat 选项,则假定 –compat=5。
有关更多信息,请参见 —features。
生成共享库时,不要使用 -Bsymbolic。
按照 C++ 语言规则,C++ 内联函数是指具有以下特征的函数,对于该函数以下陈述之一为真:
该函数的定义中使用了关键字 inline
该函数在类定义内部定义(不仅是声明)
该函数是编译器生成的类成员函数
按照 C++ 语言规则,编译器可以选择是否将调用实际内联到内联函数。C++ 编译器将调用内联到内联函数,除非下述事项之一为真:
函数太复杂
已选定 +d 选项
已选定 -g 选项,但未指定 -xOn 优化级别
缺省情况下,编译器可以内联以下代码示例中的函数 f() 和 memf2()。此外,该类具有编译器可以内联的由编译器生成的缺省构造函数和析构函数。使用 +d 时,编译器不会内联 f() 和 C::mf2()(即构造函数和析构函数)。
inline int f() {return 0;} // may be inlined class C { int mf1(); // not inlined unless inline definition comes later int mf2() {return 0;} // may be inlined };
指定了调试选项 –g 时将自动启用此选项,除非还指定了优化级别 (—O 或 —xO)。
但指定调试选项 –g0 不会启用 +d。
+d 选项对使用 -xO4 或 -xO5 时执行的自动内联没有影响。
–g0 和 –g
使用该选项与在源文件开头包含 #define 指令等效。可以使用多个 -D 选项。
有关编译器预定义宏的列表,请参见 CC(1) 手册页。
该选项传递给 ld。
该选项只能在命令行出现一次。
|
如果没有指定 -d 选项,则使用 –dy。
在 64 位环境中,许多系统库只能用作共享动态库。其中包括 libm.so 和 libc.so(不提供 libm.a 和 libc.a)。因此,在 64 位 Oracle Solaris 操作系统中,-Bstatic 和 -dn 可能会导致产生链接错误。这些情况下应用程序必须与动态库链接。
如果将此选项与动态库结合使用,将导致致命错误。大多数系统库仅作为动态库可用。
ld(1) 手册页和《链接程序和库指南》
(SPARC) 已过时,不要使用。请使用 -xmemalign=8s。有关更多信息,请参见A.2.145 -xmemalign=ab。
在 x86 平台上会在无提示的情况下忽略此选项。
显示但不编译驱动程序所生成的子命令。
该选项指示驱动程序 CC 显示但不执行编译驱动程序构造的子命令。
指示 CC 驱动程序仅对 C++ 源文件运行预处理程序,并将结果发送到 stdout(标准输出)。此时,不进行编译,且不生成 .o 文件。
此选项会导致输出中包含预处理程序类型的行号信息。
要在源代码涉及模板时编译 -E 选项的输出,可能需要将 -template=no%extdef 选项与 -E 选项一起使用。如果应用程序代码使用“独立定义”模板源代码模型,使用这两个选项可能仍然无法编译 -E 选项的输出。有关更多信息,请参考有关模板的章节。
该选项用于确定预处理程序所进行的更改。例如,以下程序 foo.cc 会生成A.2.12.1 示例中所示的输出。
示例 A-1 预处理程序示例 foo.cc
#if __cplusplus < 199711L int power(int, int); #else template <> int power(int, int); #endif int main () { int x; x=power(2, 10); } .
示例 A-2 使用 -E 选项时 foo.cc 的预处理程序输出
example% CC -E foo.cc #4 "foo.cc" template < > int power (int, int); int main () { int x; x = power (2, 10); }
如果代码包含采用“独立定义”模型的模板,此选项的输出可能不能用作 C++ 编译的输入。
–P
此命令会抑制 C++ 编译器警告消息,但对错误消息没有影响。此选项适用于所有警告消息,无论这些警告消息是否已被 -errwarn 指定为导致非零退出状态。
t 是一个以逗号分隔的列表,它包含以下项中的一项或多项:tag、no% tag、%all、%none。顺序是很重要的;例如 %all,no%tag 抑制除 tag 以外的所有警告消息。下表列出了 -erroff 值。
表 A-2 -erroff 值
|
缺省值为 -erroff=%none。指定 -erroff 与指定 -erroff=%all 等效。
例如,-erroff=tag 将抑制由该标记指定的警告消息。另外,-erroff=%all,no% tag 抑制所有警告信息,由 tag 标识的消息除外。
可以使用 -errtags=yes 选项显示警告消息的标记。
使用 -erroff 选项只能抑制来自 C++ 编译器前端且在使用 -errtags 选项时显示标记的警告消息。
-errtags 和 -errwarn
显示来自 C++ 编译器前端且可以使用 -erroff 选项抑制或使用 -errwarn 选项使其成为致命警告的每个警告消息的消息标记。
a 可以是 yes 或 no。缺省值为 -errtags=no。指定 -errtags 与指定 -errtags=yes 等效。
来自 C++ 编译器驱动程序的消息以及编译系统的其他组件不包含错误标记。因此,无法使用 -erroff 抑制这些消息或组件,也无法使用 -errwarn 将这些消息和组件标记为致命错误。
-erroff 和 -errwarn
使用 -errwarn 会导致 C++ 编译器在出现给定的警告消息时以失败状态退出。
t 是一个以逗号分隔的列表,它包含以下项中的一项或多项:tag、no% tag、%all、%none。顺序很重要,例如如果出现除 tag 之外的任何警告,%all,no%tag 会使 cc 以致命状态退出。
下表详细列出了 -errwarn 值。
表 A-3 -errwarn 值
|
缺省值为 -errwarn=%none。单独指定 -errwarn 与 -errwarn=%all 等效。
使用 -errwarn 选项只能对来自 C++ 编译器前端且在使用了 -errtags 选项时会显示标记的警告消息进行指定,从而使编译器以失败状态退出。
由于编译器错误检查的改善和功能的增加,C++ 编译器生成的警告消息也会因发行版本而异。使用 -errwarn=%all 进行编译而不会产生错误的代码,在编译器下一个发行版本中编译时也可能出现错误。
-erroff、-errtags 和 -xwe
此选项是一个宏,可以有效地用作优化可执行文件的起点,从而获得最佳运行时性能。-fast 是一个宏,随编译器发行版本的升级而变化,并扩展为目标平台特定的多个选项。可使用 -dryrun 或 -xdryrun 选项检查 -fast 的扩展,并将 -fast 的相应选项结合到正在进行的可执行文件调优过程中。
该选项是一个宏,选择编译选项的组合用于在编译代码的机器上优化执行速度。
该选项通过扩展到以下编译选项,为大量应用程序提供了几乎最高的性能。
表 A-4 -fast 扩展
|
-fast 宏可扩展为可能影响其他指定选项的编译选项。例如,在以下命令中,-fast 宏的扩展包括了将 -xarch 还原为某个 32 位体系结构选项的 -xtarget=native。
错误:
example% CC -xarch=sparcvis2 -fast test.cc
正确:
example% CC -fast -xarch=sparcvis2 test.cc
查看每个选项的描述以确定可能的交互操作。
代码生成选项、优化级别、内建函数的优化和内联模板文件的使用可以用后续选项来覆盖(请参见示例)。指定的优化级别将覆盖以前所设置的优化级别。
–fast 选项包括 –fns–ftrap=%none,即该选项禁用所有陷阱操作。
在 x86 上,-fast 选项包括 -xregs=frameptr。有关详细信息,特别是编译混合 C、Fortran 和 C++ 源代码时,请参见该选项的介绍。
执行以下编译器命令,优化级别将为 –xO3。
example% CC –fast –xO3
执行以下编译器命令,优化级别将为 –xO5。
example% CC -xO3 –fast
如果在不同的步骤中进行编译和链接,则编译命令和链接命令中都必须有 -fast 选项。
使用 -fast 选项编译的目标二进制文件不可移植。例如,在 UltraSPARCIII 系统中用以下命令生成的二进制文件在 UltraSPARCII 系统中无法执行。
example% CC -fast test.cc
不要对依赖于 IEEE 标准浮点运算的程序使用此选项。可能会出现不同的数值结果、程序过早终止或出现意外的 SIGFPE 信号。
-fast 的扩展包括 -D_MATHERR_ERRNO_DONTCARE。
使用 -fast,编译器可以用不设置 errno 变量的等效优化代码自由替换对浮点函数的调用。并且,-fast 还可以定义宏 __MATHERR_ERRNO_DONTCARE,该宏允许编译器不再确保 errno 和在浮点函数调用后引发的浮点异常的有效性。因此,依赖于 errno 的值或者浮点函数调用之后引起的正确浮点异常的用户代码会产生不一致的结果。
解决此问题的一种方法是避免使用 -fast 编译此类代码。但是,如果需要 -fast 优化并且代码依赖于正确设置的 errno 值或在浮点库调用后引发的浮点异常,应在命令行上在 -fast 后使用以下选项进行编译,以禁止编译器优化此类库调用:
-xbuiltin=%none -U__MATHERR_ERRNO_DONTCARE -xnolibmopt -xnolibmil
要在任何平台上显示 —fast 的扩展,请运行命令 CC —dryrun —fast,如以下示例所示。
>CC -dryrun -fast |& grep ### ### command line files and options (expanded): ### -dryrun -xO5 -xarch=sparcvis2 -xcache=64/32/4:1024/64/4 \ -xchip=ultra3i -xmemalign=8s -fsimple=2 -fns=yes -ftrap=%none \ -xlibmil -xlibmopt -xbuiltin=%all -D__MATHERR_ERRNO_DONTCARE
-fns、-fsimple、-ftrap=%none、-xlibmil、-nofstore、-xO5、-xlibmopt 和 -xtarget=native
关键字 a 可以使用下表中显示的值。no% 前缀禁用关联的选项。
表 A-5 -features 值
|
该选项会累积而不覆盖。
以下选项与标准库和头文件不兼容:
no%bool
no%except
no%mutable
不要使用 -features=%all 或 -features=%none。这些关键字已过时并且在以后的发行版中可能会被删除。结果可能不可预测。
使用 -features=tmplife 选项时,程序的行为可能会发生变化。测试在使用与不使用 -features=tmplife 选项两种情况下程序是否正常运行是一种测试程序可移植性的方法。
表 3-17 和《C++ 迁移指南》
filter 必须是下表中列出的值之一。%no 前缀禁用关联的子选项。
表 A-6 -filt 值
|
如果未指定 -filt 选项或指定了 -filt 但未提供任何值,则编译器假定 -filt=%all。
以下示例显示了使用 -filt 选项编译该代码的效果。
// filt_demo.cc class type { public: virtual ~type(); // no definition provided }; int main() { type t; }
如果编译代码时不使用 -filt 选项,编译器就假定 -filt=errors,names,returns,stdlib 并显示标准输出。
example% CC filt_demo.cc Undefined first referenced symbol in file type::~type() filt_demo.o type::__vtbl filt_demo.o [Hint: try checking whether the first non-inlined, / non-pure virtual function of class type is defined] ld: fatal: Symbol referencing errors. No output written to a.out
以下命令禁止取消改编的 C++ 链接程序名称取消改编,并禁止链接程序错误的 C++ 解释。
example% CC -filt=no%names,no%errors filt_demo.cc Undefined first referenced symbol in file __1cEtype2T6M_v_ filt_demo.o __1cEtypeG__vtbl_ filt_demo.o ld: fatal: Symbol referencing errors. No output written to a.out
现在考虑以下代码:
#include <string> #include <list> int main() { std::list<int> l; std::string s(l); // error here }
如果指定了 -filt=no%stdlib,将生成以下输出:
Error: Cannot use std::list<int, std::allocator<int>> to initialize std::basic_string<char, std::char_traits<char>, std::allocator<char>>.
如果指定了 -filt=stdlib,将生成以下输出:
Error: Cannot use std::list<int> to initialize std::string .
指定了 no%names 时,returns 和 no%returns 都无效。也就是说,以下选项是相同的:
-filt=no%names
-filt=no%names,no%returns
-filt=no%names,returns
(SPARC) 启用自动生成浮点乘加指令。-fma=none 禁用这些指令的生成。-fma=fused 允许编译器通过使用浮点乘加指令,尝试寻找改进代码性能的机会。
缺省值是 -fma=none。
要使编译器生成乘加指令,最低要求是 -xarch=sparcfmaf 且优先级别至少为 -xO2。如果生成了乘加指令,编译器会标记此二进制程序,以防止该程序在不受支持的平台上执行。
乘加指令可以免除乘法和加法之间的中间舍入步骤。因此,如果使用 -fma=fused 编译,程序可能会生成不同的结果,但精度通常会增加而不是降低。
这是可扩展至 —ftrap=common(在 x86 上)和 —fns —ftrap=common(在 SPARC 上)的宏。
有关更多信息,请参见 –fns 和 –ftrap=common。
SPARC: 启用/禁用 SPARC 的非标准浮点模式。
如果使用 -fns=yes(或 -fns),则会在程序开始执行时启用非标准浮点模式。
该选项提供了一种切换使用非标准浮点模式或标准浮点模式的方法,它接在包括 –fns 的其他某些宏选项(如 –fast)后面。
在某些 SPARC 体系结构上,非标准浮点模式会禁用“逐渐下溢”,这会导致很小的结果刷新为零而不是生成次正规数。此外,还会导致次正规操作数在无提示的情况下替换为零。
对于那些硬件中不支持逐渐下溢和次正规数的 SPARC 体系结构,-fns=yes(或 -fns)可以显著提高某些程序的性能。
x86:选择/取消选择 SSE 刷新为零模式,以及非正规数为零模式(如果可用)。
此选项导致将次正规结果刷新为零。如果可用的话,此选项还导致将次正规操作数视为零。
此选项对不使用 SSE 或 SSE2 指令集的传统 x86 浮点运算没有影响。
-fns 选项可以使用下表中列出的值。
表 A-7 -fns 值
|
如果未指定 -fns,则不自动启用非标准浮点模式。进行标准 IEEE 754 浮点计算(即逐渐下溢)。
如果仅指定了 –fns,则假定 –fns=yes。
在以下示例中,-fast 扩展为多个选项,其中一个是 -fns=yes,即选择非标准浮点模式。后续 -fns=no 选项覆盖初始设置,并选择浮点模式。
example% CC foo.cc -fast -fns=no
非标准模式启动时,浮点运算可以产生不符合 IEEE 754 标准要求的结果。
如果使用 -fns 选项编译一个例程,应使用 –fns 选项编译该程序的所有例程。否则,可能会产生意外的结果。
只有编译主程序时该选项才有效。
使用 –fns=yes(或 -fns)选项时,如果程序中出现通常由 IEEE 浮点陷阱处理程序管理的浮点错误,则可能会生成警告消息。
《数值计算指南》和 ieee_sun(3M) 手册页
–fprecision 选项用于设置浮点控制字 (floating-point control word, FPCW) 中的舍入精度模式位。这些位控制基本算术运算(加、减、乘、除和平方根)结果的舍入精度。
p 必须是下表中列出的值之一。
表 A-8 -fprecision 值
|
如果 p 为 single 或 double,该选项会使舍入精度模式在程序开始执行时分别设置为 single 或 double 精度。如果 p 是 extended 或未使用 –fprecision 选项,则舍入精度模式保持为 extended 精度。
在 single 精度舍入模式下,结果将舍入到 24 个有效位;在 double 精度舍入模式下,结果将舍入到 53 个有效位。在缺省的 extended 精度模式下,结果将舍入到 64 个有效位。该模式只控制在寄存器中结果的舍入精度,而不影响范围。寄存器中所有的结果都使用了各种已扩展的双精度格式来舍入。不过,存储在内存中的结果既舍入到目标格式的范围也舍入到目标格式的精度。
float 类型的标称精度为 single。long double 类型的标称精度为 extended。
如果未指定 –fprecision 选项,舍入精度模式缺省为 extended。
该选项仅在 x86 系统上且仅在编译主程序时才有效,但如果编译 64 位 (-m64) 或 SSE2 启动的 (-xarch=sse2) 处理器,忽略此选项。在 SPARC 系统上也忽略此选项。
启动时设置有效的 IEEE 舍入模式。
此选项设置编译器在评估常量表达式时可以使用的 IEEE 754 舍入模式。此舍入模式是在程序初始化过程中在运行时建立的。
含义与 ieee_flags 子例程的含义相同,可用于更改运行时的模式。
r 必须是下表中列出的值之一。
表 A-9 -fround 值
|
如果未指定 –fround 选项,舍入模式缺省为 -fround=nearest。
如果使用 –fround=r 编译一个例程,就必须使用相同的 –fround=r 选项编译程序的所有例程。否则,可能会产生意外的结果。
只有编译主程序时该选项才有效。
请注意,使用 —xvector 或 —xlibmopt 进行编译时需要具有缺省的舍入模式。与使用 —xvector 或 —xlibmopt(或同时使用两者)编辑的库链接的程序必须确保缺省舍入生效。
该选项允许优化器制定关于浮点运算的简化假定。
如果存在 n,它必须是 0、1 或 2。
表 A-10 -fsimple 值
|
如果未指定 –fsimple,编译器将使用 -fsimple=0。
如果指定了 -fsimple 但未指定 n 值,编译器将使用 -fsimple=1。
-fast 隐含了 – fsimple=2。
该选项可以破坏 IEEE 754 的一致性。
-fast
在以下值为真时,该选项使编译器将浮点表达式或函数的值转换为赋值左侧的类型,而不是将该值保留在寄存器中:
将表达式或函数分配到变量。
表达式被强制转换为较短的浮点类型。
要禁用此选项,请使用 –nofstore 选项。在 SPARC 平台上,—fstore 和 —nofstore 都将被忽略,并且出现一条警告。
由于误差和截断,结果可能会与寄存器值所生成的结果不同。
–nofstore
设置启动时生效的IEEE 陷阱操作模式,但不安装 SIGFPE 处理程序。可以使用 ieee_handler(3M) 或 fex_set_handling(3M) 启用陷阱并同时安装 SIGFPE 处理程序。如果指定多个值,则按从左到右顺序处理列表。
t 可以为下表中所列出的值之一。
表 A-11 -ftrap 值
|
注意,选项的 [no%] 形式只用于修改 %all 和 common 值的含义,且必须与其中的一个值一起使用,如以下示例所示。选项自身的 [no%] 形式不会显式导致禁用特定的陷阱。
如果未指定 –ftrap,则编译器假定 –ftrap=%none。
–ftrap=%all,no%inexact 意味着设置除 inexact 以外的所有陷阱。
如果使用 –ftrap=t 编译一个例程,就应使用相同的 -ftrap=t 选项编译程序的所有例程。否则,可能会产生意外的结果。
使用 -ftrap=inexact 陷阱时务必谨慎。只要浮点值不能精确表示,使用 – ftrap=inexact 便会产生自陷。例如,以下语句就会产生这种情况:
x = 1.0 / 3.0;
只有编译主程序时该选项才有效。请小心使用该选项。如果要启用 IEEE 陷阱,请使用 –ftrap=common。
ieee_handler(3M) 和 fex_set_handling(3M) 手册页。
缺省情况下,在命令行上指定的所有资源文件都是使用 -xcode=pic13 进行编译的。
在从包含模板且用 -instances=extern 选项编译的文件中生成共享库时,将自动从模板缓存中包含 .o 文件引用的任何模板实例。
如果要通过指定 -G 与其他必须在编译时和链接时指定的编译器选项来创建共享对象,请确保在编译时和与生成的共享对象链接时也指定这些选项。
创建共享对象时,针对 64 位 SPARC 体系结构编译的所有目标文件也必须使用某个显式 -xcode 值进行编译,如A.2.113 -xcode=a中所推荐。
如果未指定 – c(仅编译选项),以下选项将传递给链接程序:
–dy
–G
–R
请勿使用 ld-G 生成共享库,而应使用 CC- G。CC 驱动程序会自动将 C++ 所需的多个选项传递给 ld。
使用 -G 选项时,编译器不将任何缺省 -l 选项传递到 ld 选项。如果您要使共享库具有对另一共享库的依赖性,就必须在命令行上传递必需的 -l 选项。例如,如果要使共享库依赖于 libCrun,必须在命令行上传递 -lCrun。
-dy、-xcode=pic13、–ztext ld(1) 手册页以及14.3 生成动态(共享)库。
生成附加的符号表信息,以供使用 dbx(1) 或调试器进行调试以及使用性能分析器 analyzer(1) 进行分析。
指示编译器和链接程序准备进行调试和性能分析的文件或程序。
其任务包括:
生成以目标文件和可执行文件的符号表形式表示的详细信息(称为 stabs)。
生成帮助程序函数,调试器可以调用这些函数来实现其某些功能。
如果未指定优化级别,则会禁用函数的内联生成;也就是说,在未指定优化级别时,使用此选项意味着使用了 +d 选项。将 -g 结合 -O 或 -xO 级别不会禁用内联。
禁用优化的某些级别。
如果将此选项与 –xOlevel(或其等效选项,如 -O)一起使用,将会获得一些特定的调试信息。有关更多信息,请参见A.2.151 -xOlevel。
如果使用该选项且优化级别为 -xO4 或更高,编译器会为完全优化提供尽可能多的符号信息。如果使用 -g 且不指定优化级别,将禁用函数调用的内联。(如果随 -g 指定优化级别,会启用内联。)
指定此选项时,除非还指定 -O 或 -xO,否则会自动指定 +d 选项。
要使用性能分析器的完整功能,请使用 -g 选项进行编译。虽然某些性能分析功能不需要使用 -g,但必须使用 -g 进行编译,以便查看注释的源代码、部分函数级别信息以及编译器注释消息。有关更多信息,请参见 analyzer(1) 手册页和性能分析器手册。
使用 -g 生成的注释消息描述编译器在编译程序时进行的优化和变换。使用 er_src(1) 命令来显示与源代码交叉的消息。
如果在不同的步骤中编译和链接程序,则在一个步骤中使用 -g 选项而在另一个步骤中不使用该选项不会影响程序的正确性,但会影响调试程序的能力。没有使用 -g(或 -g0)编译但使用 -g(或 -g0)链接的任何模块将不能正常进行调试。请注意,通常必须使用 -g 选项(或 -g0 选项)编译包含函数 main 的模块才能对其进行调试。
+d、–g0、–xs、analyzer(1) 手册页、er_src(1) 手册页、ld(1) 手册页以及《使用 dbx 调试程序》(介绍了有关 stabs 的详细信息)和性能分析器手册。
此选项与 –g 相同,但 +d 处于禁用状态,dbx 无法对内联函数使用步入功能。
如果指定 -g0 且优化级别为 -xO3 或更低,编译器会为近乎完全优化提供尽可能多的符号信息。尾部调用优化和后端内联被禁用。
+d、-g 和《使用 dbx 调试程序》
—g3 选项与具有附加调试符号表信息的 —g0 相同,允许 dbx 在源代码中显示宏扩展。与使用 —g0 进行编译相比,此附加符号表信息会增大生成的 .o 和可执行文件的大小。
在标准错误输出 (stderr) 中,该选项打印当前编译中包含的每个 #include 文件的路径名(每行一个)。
这是一个链接程序选项,传递给 ld。通常,-h 后面的名称应该与 –o 后面的名称完全相同。–h 和 name 之间的空格是可选的。
编译时的加载器将指定名称分配到正在创建的共享动态库中,并将该名称作为库的内部名称记录在库文件中。如果没有 –hname 选项,则没有内部名称记录在库文件中。
每个可执行文件都具有所需的共享库文件列表。当运行时链接程序将库链接到可执行文件中时,链接程序将内部名称从库复制到所需共享库文件的列表中。如果没有共享文件的内部名称,链接程序就复制共享库文件的路径。
没有使用 -h 选项生成共享库时,运行时加载器仅查找库的文件名。可以将库替换为具有相同文件名的不同库。如果共享库有内部名称,加载器会在装入文件时检查内部名称。如果内部名称不匹配,加载器不会使用替换文件。
example% CC -G -o libx.so.1 -h libx.so.1 a.o b.o c.o
将 pathname 添加到 #include 文件中的搜索路径中。
该选项用于将 pathname 添加到在其中搜索具有相对文件名(不以斜杠开头的文件名)的 #include 文件的目录列表。
编译器按以下顺序搜索用引号引住的文件(形式为 #include "foo.h"):
在包含源代码的目录中
在使用 -I 选项指定的目录(如果有)中
在编译器提供的 C++ 头文件、ANSI C 头文件和专用文件的 include 目录中
在 /usr/include 目录中
编译器按以下顺序搜索用尖括号括住的文件(形式为 #include <foo.h>):
在使用 -I 选项指定的目录(如果有)中
在编译器提供的 C++ 头文件、ANSI C 头文件和专用文件的 include 目录中
在 /usr/include 目录中
-I- 选项让您可以覆盖缺省的搜索规则。
如果指定了 -library=no%Cstd,那么编译器在其搜索路径中就不包括编译器提供的与 C++ 标准库关联的头文件。请参见11.7 替换 C++ 标准库。
如果未使用 –ptipath,编译器就会在 –Ipathname 中查找模板文件。
请使用 –Ipathname 而不是 –ptipath。
该选项会累积而不覆盖。
任何时候都不要将编译器安装区域 /usr/include、/lib 或 /usr/lib 指定为搜索目录。
-I-
更改包含文件搜索规则。
对于形式为 #include "foo.h" 的 include 文件,按以下顺序搜索目录:
1. 使用 -I 选项指定的目录(在 -I- 前后)。
2. 编译器提供的 C++ 头文件、ANSI C 头文件和专用文件的目录
3. /usr/include 目录
对于 #include <foo.h> 形式的 include 文件,按以下顺序搜索目录:
1. 使用 -I 选项指定的目录(在 -I- 后面)
2. 编译器提供的 C++ 头文件、ANSI C 头文件和专用文件的目录
3. /usr/include 目录
以下示例显示了编译 prog.cc 时使用 -I- 的结果。
prog.cc #include "a.h" #include <b.h> #include "c.h" c.h #ifndef _C_H_1 #define _C_H_1 int c1; #endif inc/a.h #ifndef _A_H #define _A_H #include "c.h" int a; #endif inc/b.h #ifndef _B_H #define _B_H #include <c.h> int b; #endif inc/c.h #ifndef _C_H_2 #define _C_H_2 int c2; #endif
以下命令显示了针对形式为 #include "foo.h" 的包含语句搜索当前目录(包含文件的目录)的缺省行为。在 inc/a.h 中处理 #include "c.h" 语句时,编译器将 inc 子目录中的 c.h 头文件包含进来。在 prog.cc 中处理 #include "c.h" 语句时,编译器将包含 prog.cc 的目录中的 c.h 文件包含进来。请注意,-H 选项指示编译器输出所包含文件的路径。
example% CC -c -Iinc -H prog.cc inc/a.h inc/c.h inc/b.h inc/c.h c.h
以下命令显示了 -I- 选项的效果。编译器处理形式为 #include "foo.h" 的语句时,并不先在包含目录中查找,而是按照通过 -I 选项指定的目录在命令行上的显示顺序搜索这些目录。在 inc/a.h 中处理 #include "c.h" 语句时,编译器包含 ./c.h 头文件而不是 inc/c.h 头文件。
example% CC -c -I. -I- -Iinc -H prog.cc inc/a.h ./c.h inc/b.h inc/c.h ./c.h
命令行上有 -I- 时,编译器从不搜索当前目录,除非在 -I 指令中显式列出了该目录。甚至是形式为 #include "foo.h" 的包含语句,也是这种情况。
只有命令行上的第一个 -I- 会导致出现所述行为。
任何时候都不要将编译器安装区域 /usr/include、/lib 或 /usr/lib 指定为搜索目录。
指示链接程序 ld 忽略任何 LD_LIBRARY_PATH 和 LD_LIBRARY_PATH_64 设置。
此选项使编译器处理 filename 的方式就相当于其是位于主源文件首行的 #include 预处理程序指令。考虑源文件 t.c:
main() { ... }
如果使用命令 cc -include t.h t.c 编译 t.c,则编译时好像源文件包含以下项:
#include "t.h" main() { ... }
编译器在其中搜索 filename 的第一个目录是当前工作目录而不是包含主源文件的目录,这就是显式包括某个文件时的情况。例如,下面的目录结构包含两个名称相同但位置不同的头文件:
foo/ t.c t.h bar/ u.c t.h
如果您的工作目录是 foo/bar,并且您使用命令 cc ../t.c -include t.h 进行编译,则编译器会包括 foo/bar 中的 t.h 而不是 foo/ 中的此文件,后者是源文件 t.c 内包含 #include 指令时的情况。
如果编译器在当前工作目录中找不到使用 -include 指定的文件,则会在正常目录路径中搜索该文件。如果您指定多个 -include 选项,则文件的包括顺序与它们在命令行中的顺序相同。
a 必须是下表中列出的值之一。
表 A-12 -instances 值
|
如果未指定 –instances,则假定 –instances=global。
使用该选项可避免在库(共享或静态)和当前对象中生成重复的模板实例。一般来说,如果程序与库共享大量实例,可以尝试使用 -instlib=filename,看看编译时间是否会减少。
使用 filename 参数指定包含可由当前编译生成的模板实例的库。filename 参数必须包含正斜杠 "/" 字符。对于相对于当前目录的路径,请使用点斜杠 "./"。
-instlib=filename 选项没有缺省值,只有在指定后才能使用。该选项可被多次指定和累积。
假定 libfoo.a 和 libbar.so 库可对与源文件 a.cc 共享的大量模板实例进行实例化。添加 -instlib=filename 并指定库可通过避免冗余有利于减少编译时间。
example% CC -c -instlib=./libfoo.a -instlib=./libbar.so a.cc
使用 -g 进行编译时,如果使用 -instlib=file 指定的库没有使用 -g 编译,那么这些模板实例不可调试。解决方法是避免在使用 -g 时使用 -instlib=file。
如果使用 -instlib 指定库,就必须与该库链接。
-template、-instances 和 -pti
SPARC: (已过时)与 –xcode=pic32 相同。
x86: 与 –Kpic 相同。
生成共享库时使用该选项编译源文件。对全局数据的每个引用都生成为全局偏移表中指针的非关联化。每个函数调用都是通过过程链接表在程序计数器 (program counter, pc) 相对寻址模式下生成的。
x86: 使用与位置无关的代码进行编译。
生成共享库时使用该选项编译源文件。对全局数据的每个引用都生成为全局偏移表中指针的非关联化。每个函数调用都是通过过程链接表在程序计数器 (program counter, pc) 相对寻址模式下生成的。
保留编译时创建的临时文件。
该选项与 –verbose=diags 一起使用,对调试很有用。
–v, –verbose
该选项传递给 ld。搜索顺序是先搜索通过 path 指定的目录,再搜索编译器提供的目录。
该选项会累积而不覆盖。
任何时候都不要将编译器安装区域 /usr/include、/lib 或 /usr/lib 指定为搜索目录。
将库 liblib.a 或 liblib.so 添加到链接程序的搜索库列表。
该选项传递给 ld。库的名称通常为 liblib.a 或 liblib.so,其中 lib 和 .a 或 .so 部分是必需的。应该使用此选项指定 lib 部分。您可以根据需要在单个命令行上放置任意数量的库。将按照使用 –Ldir 指定的顺序对库进行搜索。
请在目标文件名之后使用该选项。
该选项会累积而不覆盖。
将 -lx 放在源文件和目标文件列表之后,这样可以确保按正确顺序搜索库。
为了确保正确的库链接顺序,必须使用 -mt(而不是 -lthread)与 libthread 链接。
–Ldir 和 -mt
将指定的 CC 提供的库加入编译和链接操作中。
关键字 l 必须是下表中列出的值之一。no% 前缀禁用关联的选项。
表 A-13 -library 值
|
标准模式(缺省模式)
libCstd 库总是包括在内,除非使用 -library=%none、-library=no%Cstd、—library=stdcxx4 或 -library=stlport4 明确将其排除。
libCrun 库总是包括在内,除非使用 -library=no%Crun 明确将其排除。
始终会包括 libm 库,即使指定了 -library=%none。
要在标准模式下没有任何 C++ 库(libCrun 除外)的情况下进行链接,请使用:
example% CC -library=%none
要在标准模式下将传统 iostream Rogue tools.h++ 库包含进来,请使用:
example% CC –library=rwtools7,iostream
要在标准模式下将标准 iostream Rogue Wave tools.h++ 库包含进来,请使用:
example% CC -library=rwtools7_std
如果使用 -library 指定了库,则在编译期间会设置适当的 –I 路径。在链接期间会设置适当的 –L、–Y P、–R 路径和 –l 选项。
该选项会累积而不覆盖。
在使用区间运算库时,必须包括以下库之一: libC、libCstd 或 libiostream。
使用 -library 选项可确保针对指定库的 -l 选项按正确顺序处理。例如,对于 -library=rwtools7,iostream 和 -library=iostream,rwtools7,-l 选项都是按照 -lrwtool -liostream 顺序传递给 ld。
指定的库在系统支持库链接之前链接。
对于 —library=stdcxx4,必须在 Oracle Solarise 平台上的 /usr/include 和 /usr/lib 中安装 stdcxx Apache 库。
不能在同一个命令行上使用 -library=sunperf 和 -xlic_lib=sunperf。
在任何命令行中,最多只能使用 -library=stlport4、-library=stdcxx4 和 -library=Cstd 选项之一。
每次只能使用一个 Rogue Wave 工具库,而且不能将任何 Rogue Wave 工具库与 -library=stlport4 或 -library=stdcxx4 一起使用。
在标准模式(缺省模式)下包含传统 iostream Rogue Wave 工具库时,必须也要包含 libiostream(有关其他信息,请参见《C++ 迁移指南》。只能在标准模式下使用标准 iostream Rogue Wave 工具库。以下命令示例显示了有效使用和无效使用 Rogue Wave tools.h++ 库选项的情况。
% CC -library=rwtools7,iostream foo.cc <-- valid, classic iostreams % CC -library=rwtools7 foo.cc <-- invalid % CC -library=rwtools7_std foo.cc <-- valid, standard iostreams % CC -library=rwtools7_std,iostream foo.cc <-- invalid
如果同时包含 libCstd 和 libiostream,必须小心,不要在程序中同时使用新旧格式的 iostream(例如,cout 和 std::cout)访问同一个文件。如果从传统和标准 iostream 代码访问同一文件,那么在相同的程序中混合标准 iostream 和传统 iostream 可能会出现问题。
不链接 Crun 或任何 Cstd 库或 stlport4 库的标准模式程序无法使用 C++ 语言的所有功能。
如果指定了 -xnolib,则忽略 -library。
如果在不同的步骤中进行编译和链接,那么必须在链接命令中使用在编译命令中使用的那组 -library 选项。
stlport4、Cstd 和 iostream 库都提供了自己的 I/O 流实现。如果使用 -library 选项指定其中多个库,会导致出现不确定的程序行为。关于使用 STLport 实现的更多信息,请参见 12.2 STLport。
库的集合不稳定,会因不同的发行版本而变化。
请参见11.4.1.1 有关传统 iostream 和传统 RogueWave 工具的说明
–I、 –l、 –R 、 –staticlib、-xia、-xlang、–xnolib、忠告:、12.2.1 重新分发和支持的 STLport 库以及《Tools.h++ User’s Guide》。
有关使用 -library=no%cstd 选项以便能够使用自己的 C++ 标准库的信息,请参见11.7 替换 C++ 标准库。
指定编译的二进制对象的内存模型。
使用 -m32 来创建 32 位可执行文件和共享库。使用 -m64 来创建 64 位可执行文件和共享库。
在所有 Oracle Solaris 平台和不支持 64 位的 Linux 平台上,ILP32 内存模型(32 位 int、long、pointer 数据类型)是缺省值。在启用了 64 位的 Linux 平台上缺省为 LP64 内存模型(64 位 long 和指针数据类型)。-m64 仅允许在支持 LP64 模型的平台上使用。
使用 -m32 编译的目标文件或库无法与使用 -m64 编译的目标文件或库链接。
使用 -m32|-m64 编译的模块必须还使用 -m32 |-m64 进行链接。有关在编译时和链接时都必须指定的完整编译器选项列表,请参见3.3.3 编译时选项和链接时选项。
64 位平台上 (-m64) 使用了大量静态数据的应用程序可能还需要 -xmodel=medium。请注意,部分 Linux 平台不支持中等模型。
请注意,在早期的编译器发行版中,由 -xarch 选项中选择的指令集来指定内存模型(ILP32 或 LP64)。从 Solaris Studio 12 编译器开始,在大多数平台上,创建 64 位对象的正确方式是将 -m64 添加到命令行中。
在 Oracle Solaris 上,-m32 为缺省值。在支持 64 位程序的 Linux 系统上,-m64 -xarch=sse2 是缺省选项。
-xarch。
从目标文件的 ELF .comment 部分中删除重复的字符串。使用 -mc 选项时,会调用 mcs -c 命令。有关详细信息,请参见 mcs(1) 手册页。
SPARC:已过时。不应使用该选项。请改用 —xmemalign=2i。
从目标文件的 .comment 部分中删除所有字符串,如果提供了 string,则将 string 放入该部分。如果字符串包含空格,就必须使用引号将该字符串括入。如果使用此选项,会调用命令 mcs -d [-a string]。
使用此选项,可以通过 Oracle Solaris 线程或 POSIX 线程 API 编译和链接多线程代码。-mt=yes 选项确保库以正确的顺序链接。
此选项将 -D_REENTRANT 传递给预处理程序。
要使用 Oracle Solaris 线程,请包括 thread.h 头文件并使用 —mt=yes 选项进行编译。要在 Oracle Solaris 平台上使用 POSIX 线程,应将 pthread.h 头文件包含进来并使用 -mt=yes -lpthread 选项进行编译。
在 Linux 平台上,只有 POSIX 线程 API 可用。(Linux 平台上没有 libthread)。因此,Linux 平台上的 -mt=yes 会添加 -lpthread,而不是 -lthread。要在 Linux 平台上使用 POSIX 线程,应使用 -mt=yes 进行编译。
请注意,当使用 -G 进行编译时,-lthread 和 -lpthread 均不会自动包括在 -mt=yes 内。生成共享库时,您需要显式列出这些库。
-xopenmp 选项(用于使用 OpenMP 共享内存并行化 API)自动包含 -mt=yes。
如果使用 -mt=yes 进行编译并在单独的步骤中进行链接,则除了在编译步骤中外,还必须在链接步骤中使用 mt=yes 选项。如果使用 -mt 编译和链接一个翻译单元,则必须使用 -mt 编译和链接程序的所有单元。
-mt=yes 是编译器的缺省行为。如果不需要此行为,请使用 -mt=no 进行编译。
选项 -mt 与 -mt=yes 等效。
–xnolib、Oracle Solaris《多线程编程指南》和《链接程序和库指南》
与 –xtarget=native 相同。
取消强制表达式具有由 -fstore 调用的目标变量的精度。-nofstore 是由 -fast 调用的。-fstore 是惯用的缺省值。
–fstore
不将共享库的运行时搜索路径生成到可执行文件中。
如果可执行文件使用共享库,编译器通常会生成将运行时链接程序指向这些共享库的路径。为此,编译器会将 –R 选项传递给 ld。路径取决于安装编译器的目录。
如果客户可能会为程序引用的共享库使用不同的路径,在生成提供给这类客户的可执行文件时建议使用该选项。请参阅11.6 使用共享库。
如果使用编译器安装区域下的任何共享库,并且还使用 –norunpath,那么就应该在链接时使用 –R 选项或在运行时设置环境变量 LD_LIBRARY_PATH 来指定共享库的位置。这样做使运行时链接程序可以找到共享库。
-O 宏扩展到了 -xO3。(某些以前的发行版从 —O 扩展到 –xO2 )。
这种特殊变化会提高运行时性能。但是,对于依赖于被自动视为 volatile 的所有变量的程序,-xO3 可能不适用。可能做出此假定的典型程序包括设备驱动程序,以及实现其自己的同步基元的旧版多线程应用程序。解决方法是用 -xO2 而不是 -O 进行编译。
编译器必须存储模板实例时,它将模板实例存储在输出文件目录中的模板系统信息库中。例如,以下命令将目标文件写入 ./sub/a.o 并将模板实例写入包含在 ./sub/SunWS_cache 中的系统信息库。
example% CC -instances=extern -o sub/a.o a.cc
编译器从对应于编译器读取的目标文件的模板系统信息库读取。例如,以下命令从 ./sub1/SunWS_Cache 和 ./sub2/SunWS_cache 进行读取,并且在必要时向 ./SunWS_cache 进行写入。
example% CC -instances=extern sub1/a.o sub2/b.o
有关更多信息,请参见7.4 模板系统信息库。
filename 必须有与编译所生成文件的类型对应的适当后缀。当与 -c 一起使用时,filename 指定目标 .o 目标文件;当与 -G 一起指定时,它指定目标 .so 库文件。此选项及其参数将传递给 ld。
filename 不能与源文件是同一文件,因为 CC 驱动程序不覆盖源文件。
如果没有 +p,则编译器识别非标准预处理程序声明。
如果使用了 +p,就不定义下列宏:
sun
unix
sparc
i386
该选项不在输出中包括预处理程序类型的行号信息。
–E
已过时,请参见A.2.159 -xpg。
x86: 替换为 –xtarget=pentium。
x86: 与 –Kpic 相同。
SPARC: 与 –xcode=pic13 相同。
x86: 与 -Kpic 相同。
与 –template=wholeclass 相同。
为模板源文件指定附加搜索目录。
该选项可替换 –Ipathname 设置的正常搜索路径。如果使用了 -ptipath 选项,编译器将在该路径上查找模板定义文件,并忽略 –Ipathname 选项。
如果使用 –Ipathname 选项而非 –ptipath,可以减少混淆情况。
该选项会累积而不覆盖。
–Ipathname 和7.5.2 定义搜索路径
与 –instances=static 相同。
与 –verbose=template 相同。
要传递多个选项,按照逗号分隔列表的顺序指定它们。可以对使用 -Qoption 传递给组件的选项进行重新排序。驱动程序识别的选项将按正确顺序排列。对于驱动程序已识别的选项,请勿使用 -Qoption。例如,C++ 编译器识别用于链接程序 (ld) 的 -z 选项。如果发出类似于以下示例的命令,-z 选项将按顺序传递给链接程序。
CC -G -zallextract mylib.a -zdefaultextract ... // correct
但是,如果如下例所示来指定命令,-z 选项可能会重新排序,因而得到的结果可能不正确。
CC -G -Qoption ld -zallextract mylib.a -Qoption ld -zdefaultextract ... // error
phase 必须是下表中列出的值之一。
表 A-14 -Qoption 值
|
在以下命令中,当 CC 驱动程序调用 ld 时,–Qoption 会将 –i 和 –m 选项传递给 ld。
example% CC -Qoption ld -i,-m test.c
请注意避免无法预料的结果。例如,以下选项序列:
-Qoption ccfe -features=bool,iddollar
被解释为:
-Qoption ccfe -features=bool -Qoption ccfe iddollar
正确的用法为
-Qoption ccfe -features=bool,-features=iddollar
这些功能不需要 —Qoption,仅用作示例。
与 –Qoption 相同。
使 CC 驱动程序生成类型为 sourcetype 的输出。
Sourcetype 后缀是在下表中定义的:
表 A-15 -Qproduce 值
|
与 –Qproduce 相同。
将动态库搜索路径生成到可执行文件中。
该选项传递给 ld。
如果没有 -R 选项,则在输出对象中记录且传递给运行时链接程序的库搜索路径取决于 -xarch 选项指定的目标体系结构指令。未提供 -xarch 时,将假定 -xarch=generic。
检查 —dryrun 的输出和传递给链接程序 ld 的 —R 选项,以查看编译器假定的缺省路径。
该选项会累积而不覆盖。
如果定义了环境变量 LD_RUN_PATH 且指定了 –R 选项,则扫描 –R 指定的路径而忽略 LD_RUN_PATH 指定的路径。
–norunpath 和《链接程序和库指南》。
编译并仅生成汇编代码。
该选项使 CC 驱动程序编译程序并输出汇编源文件,但不汇编程序。汇编源文件名称的后缀为 .s。
该选项从输出可执行文件中删除所有符号信息。该选项传递给 ld。
指示要静态链接由 -library 选项(包括其缺省值)、-xlang 选项和 -xia 选项指定的 C++ 库。
l 必须是下表中列出的值之一。
表 A-16 -staticlib 值
|
如果没有指定 –staticlib,则假定 –staticlib=%none。
以下命令静态链接 libCrun,因为 Crun 是 –library 的缺省值:
example% CC –staticlib=Crun (correct)
但以下命令并不链接 libgc,因为只有使用 -library 选项显式指定才链接 libgc:
example% CC –staticlib=gc (incorrect)
要静态链接 libgc,请使用以下命令:
example% CC -library=gc -staticlib=gc (correct)
以下命令会动态链接 librwtool 库。因为 librwtool 不是缺省库且未使用 -library 选项选择它,因此 -staticlib 不起作用:
example% CC -lrwtool -library=iostream \ -staticlib=rwtools7 (incorrect)
以下命令静态链接 librwtool 库:
example% CC -library=rwtools7,iostream -staticlib=rwtools7 (correct)
以下命令将动态链接 Sun 性能库,因为 -library=sunperf 必须与 -staticlib=sunperf 结合使用,-staticlib 选项才能对这些库的链接有效:
example% CC -xlic_lib=sunperf -staticlib=sunperf (incorrect)
此命令静态链接 Sun 性能库:
example% CC -library=sunperf -staticlib=sunperf (correct)
该选项会累积而不覆盖。
除缺省情况下隐式选择的 C++ 库之外,-staticlib 选项仅对使用 -xia 选项、-xlang 选项以及 -library 选项显式选择的 C++ 库有效。Cstd 和 Crun 是缺省选择的。
library 的允许值集合不确定,会随发行版的不同而异。
在 Oracle Solaris 平台上,系统库不可用作静态库。
-library 和11.5 静态链接标准库
可在运行时性能因 C++ iostream 和 C stdio 之间的同步而降低时使用此选项。仅当您在相同的程序中使用 iostream 写入 cout 以及使用 stdio 写入 stdout 时,才需要同步。C++ 标准要求同步,因此缺省情况下 C++ 编译器打开同步。但是,不使用同步时,应用程序性能通常更佳。如果您的程序既不写入 cout 也不写入 stdout,则可以使用选项 -sync_stdio=no 关闭同步。
如果未指定 -sync_stdio,编译器会将其设置为 -sync_stdio=yes。
请看以下示例:
#include <stdio.h> #include <iostream> int main() { std::cout << "Hello "; printf("beautiful "); std::cout << "world!"; printf("\n"); }
使用同步时,程序自行打印在一行中
Hello beautiful world! :
不使用同步时,输出会变得杂乱。
此选项仅对链接可执行文件有效,对库无效。
为临时文件定义目录。
该选项设置目录的路径名称,用于存储在编译过程中生成的临时文件。对于 -temp 设置的值和 TMPDIR 值,编译器优先采用前者。
–keeptmp
opt 必须是下表中列出的值之一。
表 A-17 -template 值
|
如果未指定 -template 选项,则假定 -template=no%wholeclass,extdef。
请考虑以下代码:
example% cat Example.cc template <class T> struct S { void imf() {} static void smf() {} }; template class S <int>; int main() { } example%
指定了 -template=geninlinefuncs 时,即使在程序中没有调用 S 的两个成员函数,也会在目标文件中生成它们。
example% CC -c -template=geninlinefuncs Example.cc example% nm -C Example.o Example.o: [Index] Value Size Type Bind Other Shndx Name [5] 0 0 NOTY GLOB 0 ABS __fsr_init_value [1] 0 0 FILE LOCL 0 ABS b.c [4] 16 32 FUNC GLOB 0 2 main [3] 104 24 FUNC LOCL 0 2 void S<int>::imf() [__1cBS4Ci_Dimf6M_v_] [2] 64 20 FUNC LOCL 0 2 void S<int>::smf() [__1cBS4Ci_Dsmf6F_v_]
如果执行中出现严重错误,将发出堆栈跟踪。
当程序生成某些信号时,-traceback 选项会导致可执行文件向 stderr 发出堆栈跟踪、转储信息并退出。如果多个线程都生成一个信号,则只为第一个生成堆栈跟踪。
要使用回溯,请在链接时将 -traceback 选项添加到编译器命令行中。编译时也接受该选项,除非生成可执行二进制文件,否则将忽略此选项。不要将 -traceback 和 -G 一起使用来创建共享库。
表 A-18 -traceback 选项
|
如果不指定该选项,则缺省值为 -traceback=%none
只使用 -traceback 而不使用 = 符号表示 -traceback=common
注意:如果不希望进行信息转储,可以使用以下命令将信息转储文件大小限制设置为零:
% limit coredumpsize 0
-traceback 选项不影响运行时性能。
该选项会删除在命令行上通过 -D(包括 CC 驱动程序隐式放在命令行上的选项)创建的宏符号 name 的所有初始定义。该选项对任何其他预定义的宏和源文件中的宏定义都没有影响。
要查看 CC 驱动程序放在命令行上的 -D 选项,请将 -dryrun 选项添加到命令行上。
以下命令取消预定义符号 __sun 的定义。foo.cc 中的预处理程序语句(例如 #ifdef(__sun))会知道该符号已取消定义。
example% CC -U__sun foo.cc
可以在命令行上指定多个 -U 选项。
所有 -U 选项都在出现的任何 -D 选项之后处理。也就是说,如果在命令行上为 -D 和 -U 指定了相同的 name,则 name 是未定义的,而不管这些选项出现的顺序如何。
-D
与 –verbose=version 相同。
v 必须是下表中列出的值之一。no% 前缀禁用关联的选项。
表 A-19 -verbose 值
|
如果未指定 –verbose,则假定 –verbose=%none。
该选项会累积而不覆盖。
前后参数之间只能用逗号分隔。所有 -W 参数均在其余的命令行参数之后进行传递。要在参数中包括逗号,请在紧靠逗号之前使用转义符 \(反斜杠)。所有 -W 参数均在常规命令行参数之后进行传递。
例如,-Wa,-o,objfile 按该顺序将 -o 和 objfile 传递给汇编程序。此外,-Wl,-I,name 将导致链接阶段覆盖动态链接程序的缺省名称 /usr/lib/ld.so.1。
这些参数相对于其他指定的命令行选项传递给工具的顺序可能会更改后续的编译器发行版。
下表列出了 c 的可能值。
表 A-20 -W 标志
|
注意:不能使用 -Wd 将 CC 选项传递给 C++ 编译器。
识别出可能会产生意外后果的代码。使用 +w 选项时,如果函数过大而无法内联或未使用声明的程序元素,就不再生成警告。这些警告不指定源代码中的真正问题,因此不适合某些开发环境。从 +w 中删除这些警告就可以在这些环境下更主动地使用 +w。在 +w2 选项中仍可以使用这些警告。
该选项生成在下列方面有问题的构造的更多相关警告:
不可移植
可能出错
低效
如果未指定 +w,则编译器发出有关极可能是问题的构造的警告。
–w 和 +w2
发出 +w 发出的所有警告以及可能无害但可能降低程序最大可移植性的技术违规的警告。
+w2 选项不再发出关于在系统头文件中使用与实现相关的构造方面的警告。因为系统头文件是实现,所以发出警告是不合适的。从 +w2 删除这些警告可以更主动地使用该选项。
+w
该选项使编译器不输出警告消息。但不能抑制某些警告(尤其是有关严重记时错误的警告)。
+w
将 arg 传递给链接程序 ld(1)。与 —z arg 等效
与 –features=iddollar 相同。
(仅限 Solaris x86/x64)-xaddr32=yes 编译标志将生成的可执行文件或共享对象限定于 32 位地址空间。
以这种方式编译的可执行文件会导致创建限定为 32 位地址空间的进程。
指定了 -xaddr32=no 时,将生成普通的 64 位二进制文件。
如果未指定 -xaddr32 选项,则假定 -xaddr32=no。
如果仅指定了 -xaddr32,则假定 -xaddr32=yes。
此选项仅适用于 -m64 编译,并且仅在支持 SF1_SUNW_ADDR32 软件功能的 Oracle Solaris 平台上适用。由于 Linux 内核不支持地址空间限制,此选项在 Linux 上不可用。
链接时,如果单个目标文件是使用 -xaddr32=yes 编译的,则假定整个输出文件是使用 -xaddr32=yes 编译的。
限定为 32 位地址空间的共享对象必须由在受限的 32 位模式地址空间内执行的进程装入。
有关更多信息,请参阅《链接程序和库指南》中的 SF1_SUNW_ADDR32 软件功能定义。
指定以下命令时,C++ 编译器可以执行基于类型的别名分析和优化:
-xalias_level[=n]
其中 n 是 any、simple 或 compatible。
在此分析级别上,编译器假定任何类型都可以为其他类型起别名。不过尽管只是假定,但还是可以执行某些优化。
编译器假定简单的类型没有别名。存储对象必须是属于以下简单类型之一的动态类型:
|
存储对象只能通过以下类型的左值访问:
对象的动态类型
对象动态类型的 constant 或 volatile 限定版本,与对象动态类型相对应的带符号或不带符号的类型
与动态类型对象的 constant 或 volatile 限定版本对应的带符号或无符号类型
在其成员(包括递归的子集成员或包含的联合)中包括上述类型的聚集或联合类型
char 或 unsigned char type。
编译器假定布局不兼容类型没有别名。存储对象只能通过以下类型的左值访问:
对象的动态类型
对象动态类型的 constant 或 volatile 限定版本,与对象动态类型相对应的带符号或不带符号的类型
与动态类型对象的 constant 或 volatile 限定版本对应的带符号或无符号类型
在其成员(包括递归的子集成员或包含的联合)中包括上述类型的聚集或联合类型
动态类型对象的(可能是 constant 或 volatile 限定)基类类型
char 或 unsigned char type。
编译器假定所有引用的类型都与相应存储对象的动态类型是布局兼容的。两种类型在以下情况下是布局兼容的:
如果两种类型是同一类型
如果两种类型仅在不变和可变限定方面存在区别
对于每个带符号整数类型,如果存在对应(但不相同)的无符号整数类型,则这些对应类型是布局兼容的。
如果两个枚举类型具有相同的基础类型,则它们是布局兼容的。
如果两个简单旧数据 (plain old data, POD) 结构类型具有相同数量的成员,并且对应的成员(按顺序)具有布局兼容的类型,那么这两个结构类型是布局兼容的。
如果两个 POD 联合类型具有相同数量的成员,并且对应的成员(按顺序)具有布局兼容的类型,那么这两个联合类型是布局兼容的。
在某些情况下具有存储对象动态类型的引用可能是非布局兼容的:
如果 POD 联合包含了两个或两个以上共享通用初始序列的 POD 结构,且 POD 联合对象当前包含了其中一个 POD 结构,就可以检查任何 POD 结构的通用初始部分。对包含一个或多个初始成员的序列来说,如果相应成员具有布局兼容类型(适用于位字段)和相同宽度,则两个 POD 结构共享一个通用初始序列。
指向 POD 结构对象的指针(使用 reinterpret_cast 适当转换)将指向该结构的初始成员,而如果该成员是位字段则指向该结构所在的单元。
如果未指定 -xalias_level,则编译器将该选项设置为 -xalias_level=any。如果指定了 -xalias_level 但未提供值,则编译器将该选项设置为 -xalias_level=compatible。
编译器在 -xO2 和更低的优化级别不执行基于类型的别名分析。
如果要使用 reinterpret_cast 或等价的旧式强制类型转换,程序可能会违反分析假定。此外,联合类型也违反了分析假设,如以下示例所示。
union bitbucket{ int i; float f; }; int bitsof(float f){ bitbucket var; var.f=3.6; return var.i; }
为可使用 Oracle Solaris Studio 代码分析器查看的源代码生成静态分析。
使用 —xanalyze=code 进行编译并在单独的步骤中进行链接时,还需要在链接步骤中包括 —xanalyze=code。
缺省值为 —xanalyze=no。有关更多信息,请参见 Oracle Solaris Studio 代码分析器文档。
(仅限 Solaris)创建随后可由优化和检测工具 binopt(1)、code-analyzer(1)、discover(1)、collect(1) 和 uncover(1) 使用的二进制文件。
缺省值为 -xannotate=yes。指定不带值的 -xannotate 等效于 -xannotate=yes。
为优化使用优化和监测工具,-xannotate=yes 必须在编译时和链接时均有效。如果不使用优化和监测工具,则使用 -xannotate=no 进行编译和链接可以生成略小的二进制文件和库。
此选项在 Linux 系统上不可用。
生成使用模板的 C++ 归档文件时,请将在模板系统信息库中实例化的那些模板函数包括在该归档文件中。仅在使用 -instances=extern 选项编译了至少一个目标文件时才使用模板系统信息库。使用 —xar 进行编译可以根据需要自动将这些模板添加到归档文件中。
但是,由于编译器在缺省情况下不使用模板高速缓存,因此通常不需要使用 —xar 选项。您可以使用无格式 ar(1) 命令创建 C++ 代码的归档文件(.a 文件),除非某些代码是使用 —instances=extern 编译的。在此情况下(或者如果您不确定),请使用 CC —xar 命令而不是 ar 命令。
对调用 ar -c -r 指定 -xar 并重新创建归档文件。
以下命令行归档包含在库和目标文件中的模板函数。
example% CC -xar -o libmain.a a.o b.o c.o
请勿在命令行上添加来自模板数据库中的 .o 文件。
请勿直接使用 ar 命令生成归档文件。应使用 CC–xar 以确保模板实例自动包括在归档文件中。
ar(1) 手册页
指定目标指令集体系结构 (instruction set architecture, ISA)。
该选项将编译器生成的代码限制为特定指令集体系结构的指令。此选项不保证使用任何特定于目标的指令。不过,使用该选项会影响二进制程序的可移植性。
注 - 分别使用 -m64 或 -m32 选项来指定打算使用的内存模型 LP64(64 位)或 ILP32(32 位)。-xarch 选项不再指示内存模型,除非是为了与早期的发行版兼容,如下所示。
如果代码使用的 _asm 语句或内联模板(.il 文件)使用了特定于体系结构的指令,则在编译时可能需要使用相应的 —xarch 值以避免出现编译错误。
如果在不同的步骤中编译和链接,请确保在两个步骤中为 -xarch 指定了相同的值。有关在编译时和链接时都必须指定的所有编译器选项的完整列表,请参见3.3.3 编译时选项和链接时选项。
下表列出了 SPARC 和 x86 平台通用的 -xarch 关键字。
表 A-21 适用于 SPARC 和 x86 的 —xarch 标志
|
下表提供了 SPARC 平台上每个 -xarch 关键字的详细信息。
表 A-22 用于 SPARC 平台的 -xarch 标志
|
另请注意:
用 generic,sparc, sparcvis2, sparcvis3, sparcfmaf, sparcima 编译的对象二进制文件 (.o) 可以链接起来并一起执行,但只能在支持链接的所有指令集的处理器上运行。
对于任何特定选择,生成的可执行文件在传统体系结构中可能不运行或运行缓慢。而且,由于所有指令集中均未实现四精度 (long double) 浮点指令,因此编译器不在其生成的代码中使用这些指令。
下表列出了 x86 平台上的 -xarch 标志。
表 A-23 针对 x86 的 -xarch 标志
|
如果在 x86 平台上使用 —m64 编译或链接程序的任一部分,则也必须使用这些选项之一编译程序的所有部分。有关各种 Intel 指令集体系结构(SSE、SSE2、SSE3、SSSE3 等)的详细信息,请参阅 Intel-64 和 IA-32《Intel Architecture Software Developer's Manual》
另请参见1.2 x86 特殊注意事项和1.4 二进制兼容验证。
尽管可以单独使用该选项,但它是 -xtarget 选项的扩展的一部分,并且可用于覆盖由特定的 -xtarget 选项设置的 -xarch 值。例如,-xtarget=ultra2 可扩展为 -xarch=v8plusa -xchip=ultra2 -xcache=16/32/1:512/64/1。在以下命令中, -xarch=v8plusb 覆盖了由 -xtarget=ultra2 的扩展设置的 -xarch=v8plusa。
example% CC -xtarget=ultra2 -xarch=v8plusb foo.cc
不支持 –compat[=4] 与 -xarch=generic64、-xarch=native64、-xarch=v9、-xarch=v9a 或 -xarch=v9b 结合使用。
如果在进行优化时使用该选项,那么在指定体系结构上适当选择就可以提供高性能的可执行文件。但如果选择不当就会导致性能的严重降级,或导致在预定目标平台上无法执行二进制程序。
如果在不同的步骤中编译和链接,请确保在两个步骤中为 -xarch 指定了相同的值。
为多个处理器启用自动并行化。执行依赖性分析(对循环进行迭代间数据依赖性分析)和循环重构。如果优化级别不是 -xO3 或更高,则将优化级别提高到 -xO3 并发出警告。
如果要进行自己的线程管理,请勿使用 -xautopar。
要达到更快的执行速度,则该选项需要多处理器系统。在单处理器系统中,生成的二进制文件的运行速度通常较慢。
要在多线程环境中运行已并行化的程序,必须在执行之前将环境变量 OMP_NUM_THREADS 设置为大于 1 的值。如果未设置,则缺省值为 2。要使用多个线程,请将 OMP_NUM_THREADS 设置为更大的值。将 OMP_NUM_THREADS 设置为 1,则会仅使用一个线程运行。通常,应将 OMP_NUM_THREADS 设置为正在运行的系统中的可用虚拟处理器数,该值可使用 Oracle Solaris psrinfo(1) 命令确定。
如果使用 -xautopar 且在一个步骤中进行编译和链接,则链接会自动将微任务化库和线程安全的 C 运行时库包含进来。如果使用 -xautopar 并在不同的步骤中进行编译和链接,则还必须使用 -xautopar 进行链接。
(SPARC) 此选项现在已废弃,将在以后的编译器发行版中删除。请参见A.2.103 -xannotate[=yes| no]
指示编译器准备二进制文件,以便以后进行优化、转换和分析。请参见 binopt(1) 手册页。此选项可用于生成可执行文件或共享对象。如果在不同的步骤中进行编译,则在编译步骤和链接步骤中都必须有 -xbinopt:
example% cc -c -xO1 -xbinopt=prepare a.c b.c example% cc -o myprog -xbinopt=prepare a.o
如果有些源代码不可用于编译,仍可使用此选项来编译其余代码。然后,应将其用于可创建最终库的链接步骤中。在此情况下,只有用此选项编译的代码才能进行优化、转换或分析。
缺省值为 -xbinopt=off。
此选项必须与 -xO1 或更高的优化级别一起使用时才有效。使用此选项生成二进制文件时,文件大小会有所增加。
使用 -xbinopt=prepare 和 -g 编译会将调试信息包括在内,从而增加可执行文件的大小。
使用 -xbuiltin 选项可改善对调用标准库函数的代码的优化。此选项使编译器可在对性能有益时替换内函数或内联系统函数。要了解如何解读编译器注释输出来确定编译器替换了哪些函数,请参见 er_src(1) 手册页。
使用 —xbuiltin=%all 时,替换会导致 errno 的设置变得不可靠。如果您的程序依赖于 errno 的值,请不要使用此选项。
—xbuiltin=%default 仅内联未设置 errno 的函数。errno 的值在任何优化级别上都始终是正确的,并且可以可靠地检查。在 —xO3 或更低级别上使用 —xbuiltin=%default 时,编译器将确定哪些调用有利于内联,并且不内联其他调用。
-xbuiltin=%none 选项表示采用缺省编译器行为,编译器对内置函数不进行任何特殊优化。
如果没有指定 —xbuiltin,则在以优化级别 —xO1 或更高级别进行编译时缺省值为 —xbuiltin=%default,而在以 —xO0 级别进行编译时,缺省值为 —xbuiltin=%none。如果指定 —xbuiltin 时未带参数,则缺省为 —xbuiltin=%all,编译器会更积极地替换内部函数或者对标准库函数进行内联。
请注意,—xbuiltin 仅内联系统头文件中定义的全局函数,从不内联用户定义的静态函数。尝试在全局函数上进行插入的用户代码可能会导致出现不确定的行为。
宏 -fast 的扩展包括了 -xbuiltin=%all。
下面的编译器命令请求标准库调用的特殊处理。
example% CC -xbuiltin -c foo.cc
下面的编译器命令请求不要对标准库调用进行特别处理。请注意,宏 -fast 的扩展包括了 -xbuiltin=%all。
example% CC -fast -xbuiltin=%none -c foo.cc
定义要由优化器使用的高速缓存属性。此选项不保证使用每个特定的缓存属性。
注 - 尽管该选项可单独使用,但它是 -xtarget 选项扩展的一部分。它的主要用途是覆盖 -xtarget 选项提供的值。
可选属性 [/ti] 用于设置可以共享缓存的线程数。
c 必须是下表中列出的值之一。
表 A-24 -xcache 值
|
下表中介绍了高速缓存属性 si /li/ai /ti 的定义:
|
例如,i=1 指定 1 级高速缓存属性 s1/l1/a1。
如果未指定 -xcache,则假定为缺省值 –xcache=generic。该值指示了编译器在多数 SPARC 处理器上使用缓存属性来获得高性能,而不降低任何处理器的性能。
如果没有为 t 指定值,则缺省值为 1。
–xcache=16/32/4:1024/32/1 指定以下值:
16 K 字节,32 字节行大小,四路关联
1024 K 字节,32 字节行大小,直接映射关联
–xtarget=t
提供此选项只是为了方便从 char 类型定义为 unsigned 的系统中迁移代码。如果不是从这样的系统中迁移,最好不要使用该选项。只有那些依赖字符类型符号的程序才需要重写,它们要改写成显式指定带符号或者无符号。
可以将 o 替换为下表中列出的值之一。
表 A-25 -xchar 值
|
如果未指定 -xchar,编译器将假定 -xchar=s。
如果指定了 -xchar 但未指定值,编译器将假定 -xchar=s。
-xchar 选项仅会更改使用 -xchar 编译的代码中 char 类型的值范围。该选项不会更改任何系统例程或头文件中 char 类型的值范围。具体来讲,当指定了此选项时,limits.h 定义的 CHAR_MAX 和 CHAR_MIN 值不会更改。因此,CHAR_MAX 和 CHAR_MIN 不再表示无格式 char 中可编码的值的范围。
如果使用 -xchar=unsigned,则在将 char 与预定义的系统宏进行比较时要特别小心,因为宏中的值可能带符号。对于任何返回错误代码而且可以用宏来访问错误代码的例程,此情况是最常见的。错误代码一般是负值,因此在将 char 与此类宏中的值进行比较时,结果始终为假。负数永远不等于无符号类型的值。
绝不要使用 -xchar 为通过库导出的任何接口编译例程。Oracle Solaris ABI 将 char 类型指定为带符号,并且系统库的行为也与此相适应。目前还未对系统库针对将 char 指定为无符号的效果进行广泛测试。可以不使用该选项,而是修改代码使其与 char 类型是否带符号没有关联。类型 char 的符号种类因编译器和操作系统而异。
使用 -xcheck=stkovf 进行编译将增加对单线程程序中的主线程以及多线程程序中的从属线程堆栈进行堆栈溢出运行时检查。如果检测到堆栈溢出,则生成 SIGSEGV。有关如何以与其他地址空间违规的处理方式不同的方式处理堆栈溢出导致的 SIGSEGV 的信息,请参见 sigaltstack(2)。
i 必须是下表中列出的值之一。
表 A-26 -xcheck 值
|
如果未指定 -xcheck,则编译器缺省使用 -xcheck=%none。
如果指定了没有任何参数的 -xcheck,则编译器缺省使用 -xcheck=%none。
在命令行上 -xcheck 选项不进行累积。编译器按照上次出现的命令设置标志。
–xchip 选项通过指定目标处理器来指定定时属性。该选项影响以下属性:
指令的顺序(即调度)
编译器使用分支的方法
语义上等价的其他指令可用时使用的指令
注 - 尽管该选项可单独使用,但它是 -xtarget 选项扩展的一部分。它的主要用途是覆盖 -xtarget 选项提供的值。
c 必须是下面的两个表中列出的值之一。
表 A-27 适用于 SPARC 处理器的 -xchip 值
|
表 A-28 适用于 x86/x64 处理器的 -xchip 值
|
在大多数处理器中,generic 为缺省值,即指示编译器使用最佳定时属性以获得高性能,而不会显著降低任何处理器的性能。
(仅限 SPARC)指定代码地址空间。
注 - 应通过指定 -xcode=pic13 或 -xcode=pic32 生成共享对象。未使用 pic13 或 pic32 生成的共享对象不能正常工作,也可能根本无法生成。
a 必须是下表中列出的值之一。
表 A-29 -xcode 值
|
要确定是使用 –xcode=pic13 还是使用 –xcode=pic32,请使用 elfdump -c 检查全局偏移表 (Global Offset Table, GOT) 的大小并查找节头 sh_name: .got。sh_size 值是 GOT 的大小。如果 GOT 小于 8,192 字节,请指定 -xcode=pic13,否则指定 -xcode=pic32。有关更多信息,请参见 elfdump(1) 手册页。
通常,应根据以下准则来确定如何使用 -xcode:
如果要生成可执行文件,则不应该使用 -xcode=pic13 或 -xcode=pic32。
如果是生成仅用于链接到可执行文件的归档库,则不应该使用 -xcode=pic13 或 -xcode=pic32。
如果要生成共享库,请以 – xcode=pic13 开始。一旦 GOT 大小超过 8,192 字节,请使用 -xcode=pic32。
如果要生成用于链接到共享库的归档库,只能使用 -xcode=pic32。
对于 32 位体系结构,缺省值是 -xcode=abs32。64 位体系结构的缺省值是 -xcode=abs44。
生成共享动态库时,缺省 -xcode 值 abs44 和 abs32 将与 64 位体系结构一起使用。但指定 -xcode=pic13 或 -xcode=pic32。在 SPARC 上使用 –xcode=pic13 和 –xcode=pic32 时存在两项名义性能开销:
用 –xcode=pic13 或 –xcode=pic32 编译的例程会在入口点执行一些附加指令,以将寄存器设置为指向用于访问共享库的全局变量或静态变量的表 (_GLOBAL_OFFSET_TABLE_)。
对全局或静态变量的每次访问都会涉及通过 _GLOBAL_OFFSET_TABLE_ 的额外间接内存引用。如果是使用 -xcode=pic32 进行编译,则对于每个全局和静态内存引用还要执行另外两个指令。
在考虑上述成本时,请记住:由于受到库代码共享的影响,使用 -xcode=pic13 和 -xcode=pic32 会大大减少系统内存需求。共享库中使用 -xcode=pic13 或 – xcode=pic32 编译的每页代码都可以供使用该库的每个进程共享。如果共享库中的代码页包含非 pic(即绝对)内存引用,即使仅包含单个非 pic 内存引用,该页也将变为不可共享,而且每次执行使用该库的程序时都必须创建该页的副本。
确定是否已经使用 -xcode=pic13 或 –xcode=pic32 编译了 .o 文件的最简单方法是使用 nm 命令:
% nm file.o | grep _GLOBAL_OFFSET_TABLE_ U _GLOBAL_OFFSET_TABLE_
包含与位置无关的代码的 .o 文件将包含对 _GLOBAL_OFFSET_TABLE_ 无法解析的外部引用(用字母 U 标记)。
要确定是使用 –xcode=pic13 还是使用 –xcode=pic32,应使用 nm 确定库中使用或定义的不同全局变量和静态变量的数量。如果 _GLOBAL_OFFSET_TABLE_ 的大小小于 8,192 字节,就可以使用 -Kpic。否则,就必须使用 -xcode=pic32。
编译器已将调试器信息格式从 stabs(“符号表”)格式迁移到“DWARF 调试信息格式”中指定的 dwarf 格式。缺省设置为 -xdebugformat=dwarf。
如果要维护读取调试信息的软件,您现在可以选择将工具从 stabs 格式转换为 dwarf 格式。
出于移植工具的目的,可以通过此选项来使用新的格式。除非您要维护读取调试器信息的软件,或者特定工具要求使用这些格式之一的调试器信息,否则不需要使用此选项。
表 A-30 -xdebugformat 标志
|
如果未指定 -xdebugformat,编译器将假定 -xdebugformat=dwarf。此选项需要一个参数。
此选项影响使用 -g 选项记录的数据的格式。即使在没有使用 -g 的情况下记录少量调试信息,此选项仍可控制其信息格式。因此,即使不使用 -g,-xdebugformat 仍有影响。
dbx 和性能分析器软件可识别 stabs 和 dwarf 格式,因此使用此选项对任何工具的功能都没有影响。
注 - Stabs 格式并不能提供当前由 dbx 使用的所有调试数据,并且某些代码可能无法成功使用 stabs 来生成调试数据。
有关更多信息,另请参见 dumpstabs(1) 和 dwarfdump(1) 手册页。
对循环进行迭代间数据相关项分析,并执行循环重构,包括循环交换、循环合并、标量替换和“死数组”赋值消除。
在 SPARC 处理器上,对于 –xO3 及更高的所有优化级别,–xdepend 缺省为 –xdepend=on。否则,–xdepend 缺省为 –xdepend=off。指定 –xdepend 的显式设置会覆盖任何缺省设置。
在 x86 处理器上,–xdepend 缺省为 –xdepend=off。指定 -xdepend 且优化级别不是 –xO3 或更高级别时,编译器会将优化级别提高到 –xO3 并发出警告。
指定不带参数的 –xdepend 等效于 –xdepend=yes。
-xautopar 中包括依赖性分析。依赖性分析在编译时完成。
依赖性分析在单处理器系统中可能很有用。但是,如果在单处理器系统上使用 –xdepend,不应该同时指定 –xautopar,因为将针对多处理器系统进行 –xdepend 优化。
–xprefetch_auto_type
要查看宏在程序中的行为方式时使用此选项。该选项提供了诸如宏定义、取消定义的宏和宏用法实例的信息,并按宏的处理顺序将输出信息输出到标准错误 (stderr)。-xdumpmacros 选项在整个文件中或在 dumpmacros 或 end_dumpmacros pragma 覆盖它之前都是有效的。请参见B.2.5 #pragma dumpmacros。
下表列出了 value 的有效参数。前缀 no% 可禁用关联的值。
表 A-31 -xdumpmacros 值
|
该选项的值会累积,因此指定 -xdumpmacros=sys -xdumpmacros=undefs 与 -xdumpmacros=undefs,sys 的效果相同。
注 - 子选项 loc、conds 和 sys 是 defs、undefs 和 use 选项的限定符。使用 loc、conds 和 sys 本身并不会生成任何结果。例如,使用 -xdumpmacros=loc,conds,sys 不会生成什么结果。
指定不带任何参数的 -xdumpmacros 缺省设置为 -xdumpmacros=defs,undefs,sys。未指定 -xdumpmacros 时的缺省值为 -xdumpmacros=%none。
如果使用选项 -xdumpmacros=use,no%loc,则使用的每个宏名称只输出一次。但是,如果要了解更多详细信息,请使用选项 -xdumpmacros=use,loc,这样每次使用宏时都会打印位置和宏名称。
例如以下文件 t.c:
example% cat t.c #ifdef FOO #undef FOO #define COMPUTE(a, b) a+b #else #define COMPUTE(a,b) a-b #endif int n = COMPUTE(5,2); int j = COMPUTE(7,1); #if COMPUTE(8,3) + NN + MM int k = 0; #endif
以下示例显示了使用 defs、undefs、sys 和 loc 参数时文件 t.c 的输出。
example% CC -c -xdumpmacros -DFOO t.c #define __SunOS_5_9 1 #define __SUNPRO_CC 0x590 #define unix 1 #define sun 1 #define sparc 1 #define __sparc 1 #define __unix 1 #define __sun 1 #define __BUILTIN_VA_ARG_INCR 1 #define __SVR4 1 #define __SUNPRO_CC_COMPAT 5 #define __SUN_PREFETCH 1 #define FOO 1 #undef FOO #define COMPUTE(a, b) a + b example% CC -c -xdumpmacros=defs,undefs,loc -DFOO -UBAR t.c command line: #define __SunOS_5_9 1 command line: #define __SUNPRO_CC 0x590 command line: #define unix 1 command line: #define sun 1 command line: #define sparc 1 command line: #define __sparc 1 command line: #define __unix 1 command line: #define __sun 1 command line: #define __BUILTIN_VA_ARG_INCR 1 command line: #define __SVR4 1 command line: #define __SUNPRO_CC_COMPAT 5 command line: #define __SUN_PREFETCH 1 command line: #define FOO 1 command line: #undef BAR t.c, line 2: #undef FOO t.c, line 3: #define COMPUTE(a, b) a + b
以下示例说明了 use、loc 和 conds 参数如何报告文件 t.c 中宏的行为:
example% CC -c -xdumpmacros=use t.c used macro COMPUTE example% CC -c -xdumpmacros=use,loc t.c t.c, line 7: used macro COMPUTE t.c, line 8: used macro COMPUTE example% CC -c -xdumpmacros=use,conds t.c used macro FOO used macro COMPUTE used macro NN used macro MM example% CC -c -xdumpmacros=use,conds,loc t.c t.c, line 1: used macro FOO t.c, line 7: used macro COMPUTE t.c, line 8: used macro COMPUTE t.c, line 9: used macro COMPUTE t.c, line 9: used macro NN t.c, line 9: used macro MM
例如文件 y.c:
example% cat y.c #define X 1 #define Y X #define Z Y int a = Z;
以下示例基于 y.c 中的宏显示了 -xdumpmacros=use,loc 的输出:
example% CC -c -xdumpmacros=use,loc y.c y.c, line 4: used macro Z y.c, line 4: used macro Y y.c, line 4: used macro X
Pragma dumpmacros/end_dumpmacros 会覆盖 -xdumpmacros 命令行选项的作用域。
仅检查语法和语义错误。指定 -xe 时,编译器不生成任何目标代码。 -xe 的输出定向到 stderr。
如果不需要通过编译生成目标文件,可使用 -xe 选项。例如,如果要尝试通过删除代码段找出导致出现错误消息的原因,可使用 -xe 加速编辑和编译周期。
–c
该选项指示编译器将函数和/或数据变量放置到单独的分段中,这样链接程序就可以使用链接程序 -M 选项指定的映射文件中的指示将这些段重新排序以优化程序性能。通常,该优化仅在缺页时间构成程序运行时间的一大部分时才有效。
对变量重新排序有助于解决对运行时性能产生负面影响的以下问题:
在内存中存放位置很近的无关变量会造成缓存和页的争用
在内存中存放位置很远的相关变量会造成不必要的过大工作集
未用到的弱变量副本会造成不必要的过大工作集,从而降低有效数据密度
为优化性能而对变量和函数进行重新排序时,需要执行以下操作:
使用 -xF 进行编译和链接。
按照性能分析器手册中关于如何生成函数的映射文件或《链接程序和库指南》中关于如何生成数据的映射文件的说明进行操作。
使用通过链接程序的 -M 选项生成的新映射文件重新链接。
在分析器下重新执行以验证是否增强。
v 可以是下表中列出的一个或多个值。no% 前缀禁用关联的值。
表 A-32 -xF 值
|
如果未指定 -xF,则缺省值为 -xF=%none。如果指定了没有任何参数的 -xF,则缺省值为 -xF=%none,func。
使用 -xF=lcldata 会限制某些地址计算优化,因此,只应在必要时才使用该标志。
analyzer(1) 和 ld(1) 手册页
显示了对每个编译器选项的简要描述。
如果启用了 -xhwcprof,编译器将生成信息,这些信息可帮助工具将分析的加载和存储指令与其所引用的数据类型和结构成员相关联(与使用 -g 生成的符号信息结合)。它将分析数据与目标的数据空间(而非指令空间)相关联。使用此选项可以对行为进行深入洞察,单独通过指令分析难以做到这一点。
可使用 -xhwcprof 编译一组指定的目标文件。但是,当应用于应用程序中的所有目标文件时,-xhwcprof 是最有用的,它能全面识别并关联分布在应用程序的目标文件中的所有内存引用。
如果在不同的步骤中进行编译和链接,最好在链接时使用 -xhwcprof。如果将来扩展为 -xhwcprof,则在链接时可能需要使用它。
-xhwcprof=enable 或 -xhwcprof=disable 的实例将会覆盖同一命令行中 -xhwcprof 的所有以前的实例。
在缺省情况下,禁用 -xhwcprof。指定不带任何参数的 -xhwcprof 与 -xhwcprof=enable 等效。
-xhwcprof 要求启用优化并选择 DWARF 调试数据格式。请注意,DWARF 格式 (-xdebugformat=dwarf) 现在是缺省格式。
组合使用 -xhwcprof 和 -g 会增加编译器临时文件的存储需求,而且高于单独指定 -xhwcprof 和 -g 所引起的增加总量。
下列命令可编译 example.cc,并可为硬件计数器分析以及针对使用 DWARF 符号的数据类型和结构成员的符号分析指定支持:
example% CC -c -O -xhwcprof -g -xdebugformat=dwarf example.cc
有关基于硬件计数器的分析的更多信息,请参见性能分析器手册。
注 - C++ 区间运算库与 Fortran 编译器中实现的区间运算相兼容。
在 x86 平台上,该选项需要 SSE2 指令集支持。
-xia 选项是一个扩展到 -fsimple=0 -ftrap=%none -fns=no -library=interval 的宏。如果使用区间并通过为 -fsimple、-ftrap、-fns 或 -library 指定不同的标志来覆盖 -xia 设置的内容,则可能会导致编译器出现不正确的行为。
要使用区间运算库,请将 <suninterval.h> 包含进来。
在使用区间运算库时,必须包括以下库之一:Cstd 或 iostream。有关包括这些库的信息,请参见 -library。
如果您使用区间并为 -fsimple、-ftrap 或 -fns 指定了不同的值,则您的程序可能显示不正确的行为。
C++ 区间运算处于实验阶段且正在改进。具体功能可能随发行版本而变。
-library
指定在 -xO3 或更高的优化级别优化器可以内联用户编写的哪些例程。
func-spec 必须是下表中列出的值之一。
表 A-33 -xinline 值
|
只有使用了 -xipo[=1|2] 时,才会内联要编译的文件中的例程。优化器决定适合内联的例程。
如果未指定 -xinline 选项,则编译器假定 -xinline=%auto。
如果指定了没有任何参数的 -xinline=,则不内联函数,而不管优化级别是什么。
要启用自动内联同时禁用内联声明为 int foo() 的函数,请使用以下命令:
example% CC -xO5 -xinline=%auto,no%__1cDfoo6F_i_ -c a.cc
要强烈要求内联声明为 int foo() 的函数,并使所有其他函数作为要内联的候选函数,请使用以下命令:
example% CC -xO5 -xinline=%auto,__1cDfoo6F_i_ -c a.cc
要强烈要求内联声明为 int foo() 的函数,且不允许内联任何其他函数,请使用以下命令:
example% CC -xO5 -xinline=__1cDfoo6F_i_ -c a.cc
优化级别低于 -xO3 时,-xinline 选项不起作用。在 -xO4 或更高的优化级别上,优化器会决定应该内联哪些函数,无需指定 -xinline 选项即可完成。另外,在 -xO4 或更高的优化级别上,编译器会尝试确定内联哪些函数可以提高性能。
如果出现以下任一情况,则会内联例程。
优化级别为 -xO3 或更高
认为内联有益且安全
函数在要编译的文件中,或函数在使用 -xipo[=1|2] 编译了的文件中
如果使用 -xinline 强制内联函数,实际上可能会降低性能。
指定此选项编译并检测您的程序,以供线程分析器进行分析。有关线程分析器的更多详细信息,请参见 tha(1) 手册页。
然后可使用性能分析器以 collect -r races 来运行此检测过的程序,从而创建数据争用检测实验。可以单独运行已检测的代码,但其运行速度将非常缓慢。
可指定 -xinstrument=no%datarace 来关闭线程分析器的源代码准备。这是缺省值。
指定 -xinstrument 时必须带参数。
如果在不同的步骤中进行编译和链接,则在编译和链接步骤都必须指定 -xinstrument=datarace。
此选项定义了预处理程序令牌 __THA_NOTIFY。可指定 #ifdef __THA_NOTIFY 来保护对 libtha(3) 例程的调用。
该选项也设置 -g。
-xipo 选项通过调用过程间分析传递来执行部分程序优化。它会在链接步骤中对所有目标文件执行优化,且优化不限于只是编译命令中的那些源文件。但是,使用 -xipo 执行的整个程序优化不包括汇编 (.s) 源文件。
编译和链接大型多文件应用程序时,-xipo 选项特别有用。用该标志编译的对象目标文件具有在这些文件内编译的分析信息,这些信息实现了在源代码和预编译的程序文件中的过程间分析。但分析和优化只限于使用 -xipo 编译的目标文件,并不扩展到目标文件或库。
-xipo 选项可以使用下表中列出的值。
表 A-34 -xipo 值
|
如果未指定 -xipo,则假定 -xipo=0。
如果仅指定了 -xipo,则假定 -xipo=1。
以下示例在相同的步骤中编译和链接。
example% CC -xipo -xO4 -o prog part1.cc part2.cc part3.cc
优化器在最后一个链接步骤中在三个源文件之间执行交叉文件内联。不必一次编译所有源文件,可以分多次进行编译,每次编译时都指定 -xipo 选项。
以下示例在不同的步骤中编译和链接。
example% CC -xipo -xO4 -c part1.cc part2.cc example% CC -xipo -xO4 -c part3.cc example% CC -xipo -xO4 -o prog part1.o part2.o part3.o
在编译步骤中创建的目标文件具有在文件内部编译的附加分析信息,这样就可以在链接步骤中执行跨文件优化。
在链接步骤中使用目标文件集合时,编译器试图执行整个程序分析和优化。对于该目标文件集合中定义的任何函数或子例程 foo(),编译器做出以下两个假定:
运行时在该目标文件集合之外定义的其他例程不显式调用 foo()。
目标文件集合中的任何例程调用 foo() 时,不会插入该目标文件集合之外定义的不同版本的 foo()。
如果第一个假设对于给定的应用程序不成立,请勿使用 -xipo=2 进行编译。
如果第二个假设不成立,请不要使用 -xipo=1 也不要使用 -xipo=2 进行编译。
例如,如果对函数 malloc() 创建了您自己的版本,并使用 -xipo=2 进行编译。对于任何库中引用 malloc() 且与您的代码链接的所有函数,也都必须使用 -xipo=2 进行编译,并且需要在链接步骤中对其目标文件进行操作。由于该策略可能不适用于系统库,因此不要使用 -xipo=2 编译您的 malloc() 版本。
另举一例,如果生成了一个共享库,有两个外部调用(foo() 和 bar())分别在两个不同的源文件中。并假设 bar() 调用 foo()。如果可能会在运行时插入 foo(),则不要使用 -xipo=1 或 -xipo=2 编译 foo() 或 bar() 的源文件。否则,foo() 会内联到 bar() 中,从而导致出现错误的结果。
-xipo 选项要求优化级别至少为 -xO4。
在不同的步骤中进行编译和链接时,必须在这两个步骤中都指定 -xipo 才有效。
没有使用 -xipo 编译的对象可以自由地与使用 -xipo 编译的对象链接。
即使使用 -xipo 对库进行了编译,这些库也不参与交叉文件的过程间分析,如以下示例中所示。
example% CC -xipo -xO4 one.cc two.cc three.cc example% CC -xar -o mylib.a one.o two.o three.o ... example% CC -xipo -xO4 -o myprog main.cc four.cc mylib.a
本示例中,在 one.cc、two.cc 和 three.cc 之间以及 main.cc 和 four.cc 之间执行过程间优化,但不在 main.cc 或 four.cc 和 mylib.a 中的例程之间执行过程间优化。(第一个编译可能生成有关未定义符号的警告,但仍可执行过程间优化,因为过程间优化是编译和链接的一个步骤。)
由于执行跨文件优化时需要附加信息,因此 -xipo 选项会生成更大的目标文件。不过,该附加信息不会成为最终的二进制可执行文件的一部分。可执行程序大小的增加都是由于执行的附加优化导致的。
-xjobs
-xipo_archive 选项使编译器可在生成可执行文件之前,用通过 -xipo 编译且驻留在归档库 (.a) 中的对象文件来优化传递给链接程序的对象文件。库中包含的在编译期间优化的任何目标文件都会替换为其优化后的版本。
下表列出了 a 的可能值。
表 A-35 -xipo_archive 标志
|
如果不为 -xipo_archive 指定设置,编译器会将其设置为 -xipo_archive=none。
指定 -xipo_archive 时必须带标志。
禁用或设置 #pragma ivdep pragma 的解释(忽略向量依赖性)。
ivdep pragma 指示编译器忽略在循环中找到的部分或全部对数组引用的循环附带依赖性,以进行优化。这样,编译器就可以执行各种循环优化,例如微向量化、分发、软件流水操作等,其他情况下,无法执行这些优化。当用户知道这些依赖性无关紧要或者实际上永远不会发生时,可以使用该指令。
#pragma ivdep 指令的解释依赖于 —xivdep 选项的值。
以下列表列出了 p 的值及其含义。
忽略假定的循环附带依赖性
忽略所有循环附带向量依赖性
忽略假定的向后循环附带向量依赖性
忽略所有向后循环附带向量依赖性
不忽略任何依赖性(禁用 ivdep pragma)
提供这些解释是为了与另一个供应商对 ivdep pragma 的解释兼容。
指定 -xjobs 选项设置编译器为完成其工作创建的进程数。在多处理器计算机上,该选项可以缩短生成时间。目前,-xjobs 只能与 -xipo 选项一起使用。如果指定 -xjobs=n,过程间优化器就将 n 作为其在编译不同文件时可调用的最大代码生成器实例数。
指定 -xjobs 时务必要指定值。否则,会发出错误诊断并使编译终止。
通常,n 的安全值等于 1.5 乘以可用处理器数。如果使用的值是可用处理器数的数倍,则会降低性能,因为有在产生的作业间进行的上下文切换开销。此外,如果使用很大的数值会耗尽系统资源(如交换空间)。
出现最合适的实例之前,-xjobs 的多重实例在命令行上会互相覆盖。
以下示例在有两个处理器的系统上进行的编译,速度比使用相同命令但没有 -xjobs 选项时进行的编译快。
example% CC -xipo -xO4 -xjobs=3 t1.cc t2.cc t3.cc
禁止对命名函数 ( name) 进行与堆栈相关的优化。
禁止对所有代码进行与堆栈相关的优化。
允许对所有代码进行与堆栈相关的优化。
此选项是累积性的,可以多次出现在命令行中。例如,—xkeepframe=%all —xkeepframe=no%func1 表示应保留 func1 以外的所有函数的堆栈帧。而且,—xkeepframe 优先于 —xregs=frameptr。例如,—xkeepframe=%all —xregs=frameptr 表示应保留所有函数的堆栈,但会忽略 —xregs=frameptr 的优化。
如果命令行中未指定,编译器将采用 -xkeepframe=%none 作为缺省值。如果指定了但没有值,编译器将采用 -xkeepframe=%all
language 必须是 f77、f90、f95 或 c99。
f90 和 f95 参数等价。c99 参数表示为已使用 -xc99=%all 编译并要使用 CC 链接的对象调用 ISO 9899:1999 C 编程语言行为。
-xlang=f90 和 -xlang=f95 选项隐含了-library=f90,而 -xlang=f77 选项隐含了 -library=f77。但要进行混合语言链接,只使用 -library=f77 和 -library=f90 选项是不够的,因为只有 -xlang 选项才能确保适当的运行时环境。
要决定在混合语言链接中使用的驱动程序,请使用下列语言分层结构:
C++
Fortran 95(或 Fortran 90)
Fortran 77
C 或 C99
将 Fortran 95、Fortran 77 和 C++ 目标文件链接在一起时,请使用最高级语言的驱动程序。例如,使用下列 C++ 编译器命令来链接 C++ 和 Fortran 95 目标文件:
example% CC -xlang=f95...
要链接 Fortran 95 和 Fortran 77 目标文件,请使用如下所示的 Fortran 95 驱动程序:
example% f95 -xlang=f77...
不能在同一编译器命令中同时使用 -xlang 选项和 -xlic_lib 选项。如果要使用 -xlang 且需要在 Sun 性能库中进行链接,应改用 -library=sunperf。
请勿将 -xnolib 与 -xlang 一起使用。
如果要将并行的 Fortran 对象与 C++ 对象混合,链接行必须指定 -mt 标志。
-library 和 -staticlib
可指定 -xldscope 选项来更改外部符号定义的缺省链接程序作用域。由于更好的隐藏了实现,所以对缺省的更改会产生更快速更安全的共享库和可执行文件。
下表列出了 v 的可能值。
表 A-36 -xldscope 值
|
如果未指定 -xldscope,编译器将假定 -xldscope=global。如果指定了没有任何值的 -xldscope,则编译器就会发出错误。在到达最右边的实例之前,命令行上此选项的多个实例相互覆盖。
如果要使客户端覆盖库中的函数,就必须确保该库生成期间未以内联方式生成该函数。编译器在以下情况下会内联函数:
函数名称是使用 -xinline 指定的。
如果在 -xO4 或更高级别进行编译(在这种情况下将自动执行内联)。
如果使用内联说明符或交叉文件优化。
例如,假定库 ABC 具有缺省的分配器函数,该函数可用于库的客户端,也可在库的内部使用:
void* ABC_allocator(size_t size) { return malloc(size); }
如果在 -xO4 或更高级别生成库,则编译器将内联库组件中出现的对 ABC_allocator 的调用。如果库的客户端要用定制的版本替换 ABC_allocator,则在调用 ABC_allocator 的库组件中不能进行该替换。最终程序将包括函数的不同版本。
生成库时,用 __hidden 或 __symbolic 说明符声明的库函数可以内联生成。假定这些说明符不被客户机覆盖。请参见4.1 链接程序作用域。
用 __global 说明符声明的库函数不应内联声明,并且应该使用 -xinline 编译器选项来防止内联。
-xinline 和 -xO
使 libm 在异常情况下对于数学例程返回 IEEE 754 值。
libm 的缺省行为是兼容 XPG。
《数值计算指南》
注 - 该选项不影响 C++ 内联函数。
此选项为 libm 例程选择内联模板,从而针对当前使用的浮点选项和平台生成执行速度最快的可执行文件。
–fast 选项隐含了该选项。
-fast 和《数值计算指南》。
使用优化的数学例程库。使用此选项时,必须通过指定 -fround=nearest 来使用缺省的舍入模式。
此选项使用经过了性能优化的数学例程库,通常情况下,生成的代码运行速度较快。这样生成的代码可能与普通数学库生成的代码稍有不同,不同之处通常在最后一位上。
该库选项在命令行上的顺序并不重要。
–fast 选项隐含了该选项。
–fast、–xnolibmopt 和 -fround
已过时,不使用。改为指定 -library=sunperf。有关更多信息,请参见A.2.49 -library=l[ ,l...]。
编译器忽略此选项且不显示任何提示。
(仅限 SPARC)指示编译器在对目标文件进行优化的基础上对生成的可执行文件或动态库执行链接时优化。这些优化在链接时通过分析二进制目标代码来执行。虽然未重写目标文件,但生成的可执行代码可能与初始目标代码不同。
必须至少在部分编译命令中使用 -xlinkopt,才能使 -xlinkopt 在链接时有效。优化器仍可以对未使用 -xlinkopt 进行编译的二进制目标文件执行部分受限的优化。
-xlinkopt 优化出现在编译器命令行上的静态库代码,但会跳过出现在命令行上的共享(动态)库代码而不对其进行优化。生成共享库时(使用 -G 进行编译),也可以使用 -xlinkopt。
级别设置执行的优化级别,必须为 0、1 或 2。下表列出了优化级别:
表 A-37 -xlinkopt 值
|
如果在不同的步骤中编译,-xbinopt 必须同时出现在编译和链接步骤中:
example% cc -c -xlinkopt a.c b.c example% cc -o myprog -xlinkopt=2 a.o
请注意,仅当编译器链接时才使用级别参数。在该示例中,即使编译二进制目标文件时使用的是隐含的级别 1,链接优化器的级别仍然是 2。
指定 -xlinkopt 时若不带级别参数,则表示 -xlinkopt=1。
当编译整个程序并且使用分析反馈时,该选项才最有效。分析功能会展示代码中最常用和最不常用的部分,并指示优化器相应地进行处理。这对大型应用程序尤为重要,因为在链接时执行代码优化放置可降低指令高速缓存未命中数。此选项的常见用法如下所示:
example% cc -o progt -xO5 -xprofile=collect:prog file.c example% progt example% cc -o prog -xO5 -xprofile=use:prog -xlinkopt file.c
有关使用分析反馈的详细信息,请参见A.2.164 -xprofile=p。
使用 -xlinkopt 编译时,请不要使用 -zcombreloc 链接程序选项。
注意,使用该选项编译会略微延长链接的时间,目标文件的大小也会增加,但可执行文件的大小保持不变。使用 -xlinkopt 和 -g 编译会将调试信息包括在内,从而增加了可执行文件的大小。
此选项显示哪些循环是并行化的,通常与 -xautopar 选项一起使用。
仅对指定的 C++ 程序运行 C++ 预处理程序,请求此预处理程序生成 makefile 相关项并将结果发送到标准输出。有关 make 文件和相关项的详细信息,请参见 make(1) 手册页。
但是,-xM 只报告包含的头文件的依赖性,而不报告关联的模板定义文件的依赖性。可以使用 makefile 中的 .KEEP_STATE 功能在 make 实用程序创建的 .make.state 文件中生成所有依赖性。
以下示例:
#include <unistd.h> void main(void) {}
生成的输出如下:
e.o: e.c e.o: /usr/include/unistd.h e.o: /usr/include/sys/types.h e.o: /usr/include/sys/machtypes.h e.o: /usr/include/sys/select.h e.o: /usr/include/sys/time.h e.o: /usr/include/sys/types.h e.o: /usr/include/sys/time.h e.o: /usr/include/sys/unistd.h
如果指定 -xM 和 -xMF,编译器会将所有 makefile 依赖性信息写入使用 -xMF 指定的文件。每次预处理程序向此文件写入时即将其覆盖。
有关 makefile 和相关项的详细信息,请参见 make(1S) 手册页。
与 –xM 一样,生成 makefile 相关项,只是它不报告 /usr/include 头文件的相关项,也不报告编译器提供的头文件的相关项。
如果指定 -xM1 和 -xMF,编译器会将所有 makefile 依赖性信息写入使用 -xMF 指定的文件。每次预处理程序向此文件写入时即将其覆盖。
像 -xM 一样生成 makefile 依赖性,但编译继续。-xMD 为从 -o 输出文件名(如果指定)或输入源文件名派生的 makefile 依赖性信息生成一个输出文件,替换(或添加)后缀为 .d 的文件名。如果指定了 -xMD 和 -xMF,预处理程序会将所有 makefile 相关项信息写入到使用 -xMF 指定的文件中。不允许使用 -xMD -xMF 或 -xMD -o filename 来编译多个源文件,否则会生成错误。如果已存在依赖性文件,将覆盖该文件。
此选项用于指定 makefile 依赖性输出的文件。不能在一个命令行上使用 -xMF 为多个输入文件指定单独的文件名。不允许使用 -xMD -xMF 或 -xMMD -xMF 编译多个源文件,否则会生成错误。如果已存在依赖性文件,将覆盖该文件。
此选项用于生成不包含系统头文件的 makefile 依赖性。此选项提供的功能与 -xM1 的功能相同,但是编译会继续。-xMMD 为从 -o 输出文件名(如果指定)或输入源文件名派生的 makefile 相关项信息生成一个输出文件,替换(或添加)后缀为 .d 的文件名。如果您指定 -xMF,则编译器将改用您提供的文件名。不允许使用 -xMMD -xMF 或 -xMMD -o filename 来编译多个源文件,否则会生成错误。如果已存在依赖性文件,将覆盖该文件。
(仅限 SPARC)将数据段和文本段合并。
目标文件中的数据是只读数据,并在进程之间共享,除非使用 ld-N 进行链接。
三个选项 -xMerge -ztext -xprofile=collect 不应同时使用。-xMerge 会强制将静态初始化的数据存储到只读存储器中,-ztext 禁止在只读存储器中进行依赖于位置的符号重定位,而 -xprofile=collect 会在可写存储器中生成静态初始化的、依赖于位置的符号重定位。
ld(1) 手册页
此选项将 pragma opt 的级别限制为指定级别。v 可以为 off、1、2、3、4 或 5。缺省值为 -xmaxopt=off ,表示忽略 pragma opt。在不带参数的情况下指定 -xmaxopt 时,缺省为 -xmaxopt=5。
如果同时指定了 -xO 和 -xmaxopt,则使用 -xO 设置的优化级别不得超过 -xmaxopt 值。
(仅限 SPARC)使用 -xmemalign 选项控制编译器对数据对齐所做的假定。通过控制可能会出现非对齐内存访问的代码和出现非对齐内存访问时的处理程序,可以更轻松的将程序移植到 SPARC。
指定最大假定内存对齐和非对齐数据访问的行为。必须同时为 a(对齐)和 b(行为)提供值。a 指定最大假定内存对齐,b 指定未对齐内存访问行为。
对于可在编译时确定对齐的内存访问,编译器会为该数据对齐生成适当的装入/存储指令序列。
对于不能在编译时确定对齐的内存访问,编译器必须假定一个对齐以生成所需的装入/存储序列。
如果运行时的实际数据对齐小于指定的对齐,则未对齐的访问尝试(内存读取或写入)生成一个陷阱。对陷阱的两种可能响应是:
操作系统将陷阱转换为 SIGBUS 信号。如果程序无法捕捉到信号,则程序终止。即使程序捕捉到信号,未对齐的访问尝试仍将无法成功。
操作系统通过翻译未对齐的访问并将控制返回给程序(仿佛访问已成功正常结束)来处理陷阱。
下面列出了 -xmemalign 的对齐值和行为值。
a 的值:
假定最多 1 字节对齐。
假定最多 2 字节对齐。
假定最多 4 字节对齐。
假定最多 8 字节对齐。
假定最多 16 字节对齐。
b 的值:
解释访问并继续执行。
产生信号 SIGBUS。
对于 64 位 SPARC 体系结构:为小于或等于 4 的对齐产生信号 SIGBUS。否则,将解释访问并继续执行。
对于所有其他的体系结构,此标志等效于 i。
如果要链接到某个已编译的目标文件,并且编译该目标文件时 b 的值设置为 i 或 f,就必须指定 -xmemalign。有关在编译时和链接时都必须指定的所有编译器选项的完整列表,请参见3.3.3 编译时选项和链接时选项。
以下缺省值仅适用于未使用 -xmemalign 选项时:
-xmemalign=8i,适用于所有 32 位 SPARC 体系结构 (-m32)
-xmemalign=8s,适用于所有 64 位 SPARC 体系结构 (-m64)
在提供了 -xmemalign 选项但未指定值时,缺省值为:
-xmemalign=1i,适于所有体系结构。
下面说明了如何使用 -xmemalign 来处理不同的对齐情况。
所有内存访问均未对齐,从而导致陷阱处理非常慢。
在其他情况下正确的代码中可能会发生偶然的、有目的的、未对齐访问。
程序中未发生任何未对齐访问。
要检查可能存在的奇字节访问。
要检查可能存在的奇字节访问并要使程序工作。
(仅限 x86)-xmodel 选项使编译器可以针对 Oracle Solaris x86 平台修改 64 位对象形式,只应在要编译此类对象时指定该选项。
仅当启用了 64 位的 x64 处理器上还指定了 -m64 时,该选项才有效。
下表列出了 a 的可能值。
表 A-38 -xmodel 标志
|
此选项不累积,因此编译器根据命令行最右侧的 -xmodel 实例设置模型值。
如果未指定 -xmodel,编译器将假定 -xmodel=small。如果指定没有参数的 -xmodel,将出现错误。
不是编译所有转换单元时都需要使用此选项。只有可以确保访问的对象在可访问范围之内,才可编译选择的文件。
您应了解,不是所有的 Linux 系统都支持中等模型。
通常(不含该选项)情况下,C++ 编译器会链接多个系统库以支持 C++ 程序。使用该选项时,用于链接缺省系统支持库的 -llib 不会传递给 ld。
通常情况下,编译器按照以下顺序链接系统支持库:
使用缺省的 —compat=5 时,库为:
-lCstd -lCrun -lm -lc
对于 Linux 上的 —compat=g,库为:
—lstdc++ —lCrunG3 —lm —lc
对于 Oracle x86 上的 —compat=g,库为:
—lstdc++ —lgcc_s —lCrunG3 —lm —lc
- l 选项的顺序非常重要。-lm 选项必须位于 -lc 之前。
注 - 如果指定了 -mt 编译器选项,编译器通常先与 -lthread 链接,然后再与 -lm 链接。
要确定在缺省情况下将链接哪些系统支持库,请使用 -dryrun 选项进行编译。例如,以下命令的输出:
example% CC foo.cc -m64 -dryrun
在输出中显示以下内容:
-lCstd -lCrun -lm -lc
对于符合 C 应用程序二进制接口的基本编译(即只需要支持 C 的 C++ 程序),请使用以下命令:
example% CC -xnolib test.cc –lc
要将 libm 静态链接到具有通用体系结构指令集的单线程应用程序中,请使用以下命令:
example% CC -xnolib test.cc -lCstd -lCrun -Bstatic -lm -Bdynamic -lc
如果指定了 – xnolib,就必须按给定顺序手动链接所有必需的系统支持库。必须最后链接系统支持库。
如果指定了 -xnolib,则忽略 -library。
许多 C++ 语言功能都要求使用 libCrun(标准模式)。
系统支持库的集合不稳定,会因不同的发行版本而更改。
–library、–staticlib 和 –l
在命令行上取消 –xlibmil。
将该选项与 –fast 一起使用会忽略与优化数学库链接。
不使用数学例程库。
在命令行上 –fast 选项后面使用该选项,如下例中所示:
example% CC –fast –xnolibmopt
指定优化级别,请注意是大写字母 O 后跟数字 1、2、3、4 或 5。通常,程序执行速度取决于优化的级别。优化级别越高,运行时性能越好。不过,较高的优化级别会延长编译时间并生成较大的可执行文件。
在少数情况下,-xO2 级别的性能可能比其他优化级别好,而 -xO3 也可能胜过 -xO4。尝试用每个级别进行编译,以查看您是否会遇到这种少见的情况。
如果优化器运行时内存不足,则会尝试在较低的优化等级上重试当前过程来恢复。优化器会以在 –xOlevel 选项中指定的初始级别恢复执行后续过程。
以下几节介绍了在 SPARC 平台和 x86 平台上这五个 -xO level 优化级别如何运行。
在 SPARC 平台上:
–xO1 只执行最小量的优化 (peephole),也称为 postpass,即汇编级优化。除非使用 -xO2 或 -xO3 导致编译时间过长,或交换空间不足,否则请勿使用 -xO1。
–xO2 执行基本的局部和全局优化,包括:
归纳变量消除
局部和全局的通用子表达式消除
代数运算简化
复制传播
常量传播
非循环变体优化
寄存器分配
基本块合并
尾部递归消除
终止代码消除
尾部调用消除
复杂表达式扩展
该级别不优化外部变量或间接变量的引用或定义。
–xO3 除了执行在 –xO2 级别所执行的优化外,还会对外部变量的引用和定义进行优化。该级别不跟踪指针赋值的结果。编译未通过 volatile 适当保护的设备驱动程序或修改来自信号处理程序中的外部变量的程序时,请使用 -xO2。通常,使用此级别时会增加代码大小,除非将其与 -xspace 选项结合使用。
–xO4 除了执行 –xO3 优化外,还自动内联同一文件中的多个函数。自动内联通常会提高执行速度,但有时却会使速度变得更慢。通常,使用此级别时会增加代码大小,除非将其与 -xspace 选项结合使用。
–xO5 生成最高级别的优化。它只适用于占用大量计算机时间的小部分程序。该级别采用了占用更多编译时间或无法在某种程度上减少执行时间的优化算法。如果使用分析反馈执行该级别上的优化,则更容易提高性能。请参见A.2.164 -xprofile=p。
在 x86 平台上:
–xO1 执行基本优化。其中包括代数运算简化、寄存器分配、基本块合并、终止代码和存储消除以及 peephole 优化。
–xO2 执行局部通用子表达式消除、局部复制和常量传播、尾部递归消除以及级别 1 执行的优化。
–xO3 执行全局通用子表达式的消除、全局复制和常量传播、循环长度约简、归纳变量消除、循环变体优化以及级别 2 执行的优化。
–xO4 会自动内联同一文件中的多个函数,并执行级别为 3 时执行的优化。自动内联通常会提高执行速度,但有时却会使速度变得更慢。该级别还释放了通用的框架指针注册 (ebp)。通常该级别会增加代码的大小。
–xO5 生成最高级别的优化。该级别采用了占用更多编译时间或无法在某种程度上减少执行时间的优化算法。
如果使用 -g 或 -g0 且优化级别是 -xO3 或更低,编译器会为近乎完全优化提供尽可能多的符号信息。
如果使用 -g 或 -g0 且优化级别是 -xO4 或更高,编译器会为完全优化提高尽可能多的符号信息。
使用 -g 进行调试不会抑制 –xOlevel,但 –xOlevel 会对 –g 造成一些限制。例如,–xOlevel 选项会降低调试的作用,因此无法显示 dbx 中的变量,但仍可使用 dbx where 命令获取符号回溯。有关更多信息,请参见《使用 dbx 调试程序》。
-xipo 选项只有与 -xO4 或 -xO5 一起使用时才有效。
优化级别低于 -xO3 时,-xinline 选项不起作用。优化级别为 -xO4 时,优化器会决定应该内联哪些函数,而不管是否指定了 -xinline 选项。优化级别为 -xO4 时,编译器还会尝试确定内联哪些函数可以提高性能。如果使用 -xinline 强制内联函数,实际上可能会降低性能。
缺省为不优化。不过,只有不指定优化级别时才可能使用缺省设置。如果指定了优化级别,则没有任何选项可用来关闭优化。
如果尝试不设置优化级别,请不要指定任何隐含优化级别的选项。例如,-fast 是将优化级别设置为 -xO5 的宏选项。隐含优化级别的所有其他选项都会发出优化已设置的警告消息。不使用任何优化来编译的方法是从命令行删除所有选项或创建指定优化级别的文件。
如果在 –xO3 或 –xO4 级别上优化多个非常大的过程(一个过程有数千行代码),优化器会需要过多内存。在这些情况下,机器的性能就会降低。
为了防止性能降低,请使用 limit 命令限制单一进程可用的虚拟内存大小。请参见 csh(1) 手册页。例如,将虚拟内存限制为 4 GB:
example% limit datasize 4G
如果它达到 4 GB 的数据空间,该命令会使优化器尝试恢复。
限制不能大于机器总的可用交换空间,而且要足够的小以允许在大型编译的过程中机器可以正常使用。
数据大小的最佳设置取决于要求的优化程度、真实内存和可用虚拟内存的大小。
要查找实际的交换空间,请输入:swap– l
要查找实际的真实内存,请输入:dmesg | grep mem
-xldscope –fast、 –xprofile= p 和 csh(1) 手册页
使用 -xopenmp 选项可通过 OpenMP 指令进行显式并行化。
下表列出了 i 的值。
表 A-39 -xopenmp 值
|
如果未指定 -xopenmp,则编译器缺省使用 -xopenmp=none。
如果指定了不带参数的 -xopenmp,则编译器缺省使用 -xopenmp=parallel。
如果使用 dbx 调试 OpenMP 程序,那么编译时选用 -g 和 -xopenmp=noopt 可以在并行区设置断点并显示变量内容。
使用 OMP_NUM_THREADS 环境变量可指定在运行 OpenMP 程序时要使用的线程数。如果未设置 OMP_NUM_THREADS,则缺省使用的线程数为 2。要使用多个线程,请将 OMP_NUM_THREADS 设置为更大的值。将 OMP_NUM_THREADS 设置为 1,则会仅使用一个线程运行。通常情况下,将 OMP_NUM_THREADS 设置为运行系统上可用的虚拟处理器数,该值可使用 Oracle Solaris psrinfo(1) 命令确定。有关更多信息,请参见《Oracle Solaris Studio OpenMP API 用户指南》。
要启用嵌套并行操作,必须将 OMP_NESTED 环境变量设置为 TRUE。缺省情况下,禁用嵌套并行操作。有关详细信息,请参见《Oracle Solaris Studio OpenMP API 用户指南》。
在以后的发行版中,-xopenmp 的缺省值可能会更改。可以通过显式指定适当的优化来避免警告消息。
如果在不同的步骤中进行编译和链接,请在编译步骤和链接步骤中都指定 -xopenmp。如果要生成共享对象,这很重要。用于编译可执行文件的编译器的版本不得比使用 -xopenmp 生成 .so 的编译器低。这在编译包含 OpenMP 指令的库时尤其重要。有关在编译时和链接时都必须指定的选项的完整列表,请参见3.3.3 编译时选项和链接时选项。
为了取得最佳的性能,请确保在系统上安装了最新的 OpenMP 运行时库 libmtsk.so。
有关用于生成多重处理应用程序的 OpenMP Fortran 95、C 和 C++ 应用程序接口 (application program interface, API) 的完整摘要,请参见《Oracle Solaris Studio OpenMP API 用户指南》。
在 SPARC 上有效值包括:4K、8K、64K、512K、2M、4M、32M、256M、2G、16G 或 default。
在 x86/x64 上有效值包括:4K、2M、4M、1G 或 default。
必须指定适于目标平台的有效页面大小。如果不指定有效的页面大小,运行时将忽略该请求,且不显示任何提示。
在 Oracle Solaris 操作系统中使用 getpagesize(3C) 命令可以确定页面中的字节数。Solaris 操作系统不保证支持页面大小请求。可以使用 pmap(1) 或 meminfo(2) 来确定目标平台的页面大小。
注 - 使用该选项进行编译与使用等效的选项将 LD_PRELOAD 环境变量设置为 mpss.so.1,或在运行程序之前使用等效的选项运行 Oracle Solaris 命令 ppgsz(1) 具有相同的效果。有关详细信息,请参见 Oracle Solaris 手册页。
如果指定 -xpagesize=default,Oracle Solaris 操作系统将设置页面大小。
此选项是用于 -xpagesize_heap 和 -xpagesize_stack 的宏。这两个选项与 -xpagesize 接受相同的参数:4k、8K、64K、512K、2M、4M、32M、 256M、2G、16G 或 default。可以通过指定 -xpagesize 为它们设置相同值,也可以分别为它们指定不同的值。
除非在编译和链接时使用,否则 -xpagesize 选项不会生效。有关在编译时和链接时都必须指定的选项的完整列表,请参见3.3.3 编译时选项和链接时选项。
n 可以是 4k、8K、 64K、512K、2M、4M、 32M、256M、2G、16G 或 default。必须指定适于目标平台的有效页面大小。如果不指定有效的页面大小,运行时将忽略该请求,且不显示任何提示。
在 Oracle Solaris 操作系统中使用 getpagesize(3C) 命令可以确定页面中的字节数。Solaris 操作系统不保证支持页面大小请求。可以使用 pmap(1) 或 meminfo(2) 来确定目标平台的页面大小。
注 - 使用该选项进行编译与使用等效的选项将 LD_PRELOAD 环境变量设置为 mpss.so.1,或在运行程序之前使用等效的选项运行 Oracle Solaris 命令 ppgsz(1) 具有相同的效果。有关详细信息,请参见 Oracle Solaris 手册页。
如果指定 -xpagesize_heap=default,Oracle Solaris 操作系统将设置页面大小。
除非在编译和链接时使用,否则 -xpagesize_heap 选项不会生效。
n 可以是 4k、8K、 64K、512K、2M、4M、 32M、256M、2G、16G 或 default。必须指定适于目标平台的有效页面大小。如果不指定有效的页面大小,运行时将忽略该请求,且不显示任何提示。
在 Oracle Solaris 操作系统中使用 getpagesize(3C) 命令可以确定页面中的字节数。Oracle Solaris 操作系统不保证支持页面大小请求。可以使用 pmap(1) 或 meminfo(2) 来确定目标平台的页面大小。
注 - 使用该选项进行编译与使用等效的选项将 LD_PRELOAD 环境变量设置为 mpss.so.1,或在运行程序之前使用等效的选项运行 Oracle Solaris 命令 ppgsz(1) 具有相同的效果。有关详细信息,请参见 Oracle Solaris 手册页。
如果指定 -xpagesize_stack=default,Oracle Solaris 操作系统将设置页面大小。
除非在编译和链接时使用,否则 -xpagesize_stack 选项不会生效。
该编译器选项激活了预编译头文件特性。预编译头文件的作用是减少源代码共享同一组 include 文件的应用程序的编译时间,而且这些 include 文件往往包含大量的源代码。编译器首先从一个源文件收集一组头文件信息,然后在重新编译该源文件或者其他有同样头文件的源文件时就可以使用这些收集到的信息。编译器收集的信息存储在预编译头文件中。要使用该功能,需要指定 -xpch 和 -xpchstop 选项,并使用 #pragma hdrstop 指令。
指定 -xpch=v 时,v 可以是 collect:pch-filename 或 use:pch-filename。首次使用 -xpch 时,必须指定 collect 模式。指定 -xpch=collect 的编译命令只能指定一个源文件。在以下示例中,-xpch 选项根据源文件 a.cc 创建名为 myheader.Cpch 的预编译头文件:
CC -xpch=collect:myheader a.cc
有效的预编译头文件总是有后缀 .Cpch。在指定 pch-filename 时,您可以自己添加后缀,也可以让编译器为您添加。例如,如果指定 cc -xpch=collect:foo a.cc,则预编译头文件称为 foo.Cpch。
在创建预编译头文件时,请选取包含所有源文件之间 include 文件通用序列的源文件,预编译头文件与这些源文件一起使用。include 文件的共同序列在这些源文件之间必须是一样的。请记住,在 collect 模式中只能使用一个源文件名值。例如,CC -xpch=collect:foo bar.cc 有效,而 CC -xpch=collect:foo bar.cc foobar.cc 无效,因为它指定了两个源文件。
可指定 -xpch=use:pch-filename 以使用预编译头文件。您可以将 include 文件同一序列中任意数量的源文件指定为用于创建预编译头文件的源文件。例如,在 use 模式中命令类似于:CC -xpch=use:foo.Cpch foo.c bar.cc foobar.cc。
如果以下条件都成立,则只能使用现有的预编译的头文件。如果以下任意条件不成立,则应重新创建预编译头文件:
用于访问预编译头文件的编译器与创建预编译头文件的编译器相同。编译器的一个版本创建的预编译头文件可能无法用于另一版本(包括安装的修补程序产生的差异)。
除 -xpch 选项之外,用 -xpch=use 指定的编译器选项必须与创建预编译头文件时指定的选项相匹配。
用 -xpch=use 指定的包含头文件的集合与创建预编译头文件时指定的头文件集合是相同的。
用 -xpch=use 指定的包含头文件的内容与创建预编译头文件时指定的包含头文件的内容是相同的。
当前目录(即发生编译并尝试使用给定预编译头文件的目录)与创建预编译头文件所在的目录相同。
在用 -xpch=collect 指定的文件中预处理指令(包括 #include)的初始序列,与在用 -xpch=use 指定的文件中预处理指令的序列相同。
要在多个源文件间共享预编译头文件,这些源文件必须共享一组共同的 include 文件(按其初始标记序列)。该初始标记序列称为活前缀。活前缀必须在使用相同预编译头文件的所有源文件中解释一致。
源文件的活前缀只能包含注释和以下任意预处理程序指令:
#include #if/ifdef/ifndef/else/elif/endif #define/undef #ident (if identical, passed through as is) #pragma (if identical)
以上任何指令都可以引用宏。#else、#elif 和 #endif 指令必须在活前缀内匹配。
在共享预编译头文件的每个文件的活前缀中,每个相应的 #define 和 #undef 指令都必须引用相同的符号。例如,每个 #define 必须引用同一个值。这些指令在每个活前缀中出现的顺序也必须相同。每个相应 pragma 也必须相同,并且必须按相同顺序出现在共享预编译头文件的所有文件中。
并入预编译头文件的头文件不得违反以下约束。这里没有定义对违反上述约束的程序的编译结果。
头文件一定不要包含函数和变量定义。
头文件不得使用 __DATE__ 和 __TIME__。使用预处理宏会产生无法预料的结果。
头文件不得包含 #pragma hdrstop。
头文件的活前缀中不得使用 __LINE__ 和 __FILE__。可以在包含的头文件中使用 __LINE__ 和 __FILE__。
本节介绍了为将 -xpch 合并到生成的程序中而对 makefile 进行修改的几种可能方法。
可以通过使用辅助变量 CCFLAGS 以及 make 和 dmake 的 KEEP_STATE 功能使用隐式 make 规则。预编译头文件是在独立的步骤中生成的。
.KEEP_STATE: CCFLAGS_AUX = -O etc CCFLAGS = -xpch=use:shared $(CCFLAGS_AUX) shared.Cpch: foo.cc $(CCC) -xpch=collect:shared $(CCFLAGS_AUX) foo.cc a.out: foo.o ping.o pong.o $(CCC) foo.o ping.o pong.o
您还可以定义自己的编译规则,而无不是尝试使用辅助变量 CCFLAGS。
.KEEP_STATE: .SUFFIXES: .o .cc %.o:%.cc shared.Cpch $(CCC) -xpch=use:shared $(CCFLAGS) -c $< shared.Cpch: foo.cc $(CCC) -xpch=collect:shared $(CCFLAGS) foo.cc -xe a.out: foo.o ping.o pong.o $(CCC) foo.o ping.o pong.o
可以通过常规编译顺便生成预编译头文件,而无需使用 KEEP_STATE,但该方法要求使用显式编译命令。
shared.Cpch + foo.o: foo.cc bar.h $(CCC) -xpch=collect:shared foo.cc $(CCFLAGS) -c ping.o: ping.cc shared.Cpch bar.h $(CCC) -xpch=use:shared ping.cc $(CCFLAGS) -c pong.o: pong.cc shared.Cpch bar.h $(CCC) -xpch=use:shared pong.cc $(CCFLAGS) -c a.out: foo.o ping.o pong.o $(CCC) foo.o ping.o pong.o
可使用 -xpchstop=file 选项指定在使用 -xpch 选项创建预编译头文件时要考虑的最后一个 include 文件。在命令行上使用 -xpchstop 与将 hdrstop pragma 置于第一个(引用使用 cc 命令指定的每个源文件中的 file 的)包含指令之后等效。
在以下示例中,-xpchstop 选项指定了预编译头文件的活前缀以包含 projectheader.h 结束。因此,privateheader.h 不是活前缀的一部分。
example% cat a.cc #include <stdio.h> #include <strings.h> #include "projectheader.h" #include "privateheader.h" . . . example% CC -xpch=collect:foo.Cpch a.cc -xpchstop=projectheader.h -c
-xpch 和 pragma hdrstop
(仅限 Solaris)生成可移植的可执行代码 (Portable Executable Code, PEC) 库。此选项将程序中间表示置于目标文件和二进制文件中。该二进制文件可在以后用于调整和故障排除。
使用 -xpec 生成的二进制文件通常会比未使用 -xpec 生成的二进制文件大五到十倍。
如果不指定 -xpec,则编译器会将其设置为 -xpec=no。如果您指定 -xpec,但不提供标志,则编译器会将其设置为 -xpec=yes。
编译以便使用 gprof 分析器进行分析。
-xpg 选项可编译自分析代码,以便收集可使用 gprof 分析的数据。该选项调用运行时记录机制,该机制会在程序正常终止时生成 gmon.out 文件。
注 - 如果指定了 -xpg,则 -xprofile 将没什么用处。两者不能准备或使用对方提供的数据。
在 64 位 Solaris 平台上,使用 prof(1) 或 gprof(1) 生成分析,在 32 位 Solaris 平台上,则只使用 gprof 生成分析,分析中包含大概的用户 CPU 时间。这些时间来自主可执行文件中的例程以及共享库中例程(链接可执行文件时将共享库指定为链接程序参数)的 PC 样例数据。其他共享库(在进程启动后使用 dlopen(3DL) 打开的库)不进行分析。
在 32 位 Solaris 系统中,使用 prof(1) 生成的分析仅限于可执行文件中的例程。32 位共享库通过用 -xpg 和 gprof(1) 链接可执行程序可以进行分析。
在 x86 系统中,-xpg 与 -xregs=frameptr 不兼容,这两个选项不应一起使用。还请注意,-fast 中包括 -xregs=frameptr。
Oracle Solaris 10 软件不包括使用 -p 编译的系统库。因此,在 Solaris 10 平台上收集的分析不包含系统库例程的调用计数。
如果分别进行编译和链接,且使用 –xpg 进行编译,应确保使用 –xpg 进行链接。有关在编译时和链接时都必须指定的选项的完整列表,请参见3.3.3 编译时选项和链接时选项。
使用 -xpg 编译以便进行 gprof 分析的二进制文件不应与 binopt(1) 一起使用,因为它们不兼容并可能导致内部错误。
–xprofile=p、analyzer(1) 手册页和性能分析器手册。
使用此选项可以帮助调试要移植到 64 位环境的代码。具体来说,该选项会针对遇到的问题发出警告,例如:类型(包括指针)的截断,符号扩展以及位包装更改,将代码从诸如 V8 的 32 位体系结构移植到诸如 V9 的 64 位体系结构时经常会遇到这些问题。
除非您也在 64 位模式 (—m64) 下进行编译,否则此选项没有任何效果。
下表列出了v 的有效值:
表 A-40 -xport64 值
|
如果未指定 -xport64,则缺省值为 -xport64=no。如果指定了 -xport64 但未指定标志,则缺省值为 -xport64=full。
本节提供了可以导致类型截断、符号扩展和对位包装更改的代码示例。
在移植到诸如 SPARC V9 的 64 位体系结构时,数据可能会被截断。截断可能会因赋值(初始化时)或显式强制类型转换而隐式地发生。两个指针的差异在于 typedef ptrdiff_t,它在 32 位模式下是 32 位整型,而在 64 位模式下是 64 位整型。将较长的整型截断为较小的整型会生成警告,如下示例所示。
example% cat test1.c int x[10]; int diff = &x[10] - &x[5]; //warn example% CC -c -m64 -Qoption ccfe -xport64=full test1.c "test1.c", line 3: Warning: Conversion of 64-bit type value to "int" causes truncation. 1 Warning(s) detected. example%
可使用 -xport64=implicit 禁用 64 位编译模式下显式强制类型转换导致数据截断时出现截断警告。
example% CC -c -m64 -Qoption ccfe -xport64=implicit test1.c "test1.c", line 3: Warning: Conversion of 64-bit type value to "int" causes truncation. 1 Warning(s) detected. example%
在移植到 64 位架构过程中出现的另一个常见问题是指针的截断。该问题在 C++ 中始终是错误。如果指定了 -xport64,导致此类截断的操作(如将指针强制转换为整型)可能会导致在 64 位 SPARC 体系结构中出现错误诊断。
example% cat test2.c char* p; int main() { p =(char*) (((unsigned int)p) & 0xFF); // -m64 error return 0; } example% CC -c -m64 -Qoption ccfe -xport64=full test2.c "test2.c", line 3: Error: Cannot cast from char* to unsigned. 1 Error(s) detected. example%
还可以使用 -xport64 选项来检查这种情况:标准 ISO C 值保留规则允许在无符号整型的表达式中进行带符号整数值的符号扩展。这种符号扩展会产生细微的运行时错误。
example% cat test3.c int i= -1; void promo(unsigned long l) {} int main() { unsigned long l; l = i; // warn promo(i); // warn } example% CC -c -m64 -Qoption ccfe -xport64=full test3.c "test3.c", line 6: Warning: Sign extension from "int" to 64-bit integer. "test3.c", line 7: Warning: Sign extension from "int" to 64-bit integer. 2 Warning(s) detected.
可使用 -xport64 生成对长位字段的警告。出现这种位字段时,位字段的包装可能会显著更改。在成功移植到 64 位架构之前,依赖于假定的任何程序都需要重新检查,该假定与包装位字段的方法有关。
example% cat test4.c #include <stdio.h> union U { struct S { unsigned long b1:20; unsigned long b2:20; } s; long buf[2]; } u; int main() { u.s.b1 = 0XFFFFF; u.s.b2 = 0XFFFFF; printf(" u.buf[0] = %lx u.buf[1] = %lx\n", u.buf[0], u.buf[1]); return 0; } example%
64 位 SPARC 系统 (-m64) 上的输出:
example% u.buf[0] = ffffffffff000000 u.buf[1] = 0
请注意,仅当使用 -m64 以 64 位模式编译时,才会生成警告。
显式预取只应在度量支持的特殊环境下使用。
下表列出了 a 的可能值。
表 A-41 -xprefetch 值
|
使用 -xprefetch 和 -xprefetch=auto 时,编译器就可以将预取指令自由插入到它生成的代码中。该操作会提高支持预取的体系结构的性能。
如果是在大型多处理器上运行计算密集型代码,则使用 -xprefetch=latx:factor 可以提高性能。该选项指示代码生成器按照指定的因子调节在预取及其相关的装入或存储之间的缺省延迟时间。
预取延迟是从执行预取指令到所预取的数据在高速缓存中可用那一刻之间的硬件延迟。在确定发出预取指令到发出使用所预取数据的装入或存储指令之间的间隔时,编译器就采用预取延迟值。
注 - 在预取和装入之间采用的延迟可能与在预取和存储之间采用的延迟不同。
编译器可以在众多计算机与应用程序间调整预取机制,以获得最佳性能。这种调整并非总能达到最优。对于占用大量内存的应用程序,尤其是要在大型多处理器上运行的应用程序,可以通过增加预取延迟值来提高性能。要增加值,请使用大于 1 的因子。介于 .5 和 2.0 之间的值最有可能提供最佳性能。
对于数据集完全位于外部高速缓存中的应用程序,可以通过减小预取延迟值来提高性能。要减小值,请使用小于 1 的因子。
要使用 -xprefetch=latx:factor 选项,请首先使用接近 1.0 的因子值并对应用程序运行性能测试。然后适当增加或减小该因子,并再次运行性能测试。继续调整因子并运行性能测试,直到获得最佳性能。以很小的增量逐渐增加或减小因子时,前几步中不会看到性能差异,之后会突然出现差异,然后再趋于稳定。
缺省值为 -xprefetch=auto,explicit。此缺省值会对实质上具有非线性内存访问模式的应用程序造成负面影响。要覆盖该缺省值,请指定 -xprefetch=no%auto,no%explicit。
除非使用参数 no%auto 或参数 no 进行显式覆盖,否则使用缺省值 auto。例如,-xprefetch=explicit 与 -xprefetch=explicit,auto 相同。
除非使用参数 no%explicit 或 no 进行显式覆盖,否则使用缺省值 explicit。例如,-xprefetch=auto 与 -xprefetch=auto,explicit 相同。
如果仅指定了 -xprefetch,则假定为 -xprefetch=auto,explicit。
如果启用了自动预取,但未指定延迟因子,则假定 -xprefetch=latx:1.0。
该选项会累积而不覆盖。
sun_prefetch.h 头文件提供了用于指定显式预取指令的宏。这些预取可能位于对应于宏出现位置的可执行文件中。
要使用显式预取指令,必须在适当的体系结构上,将 sun_prefetch.h 包含进来,并且从编译器命令中排除 -xprefetch 或者使用 -xprefetch、-xprefetch=auto,explicit 或 -xprefetch=explicit。
如果调用宏并包含 sun_prefetch.h 头文件,但指定 -xprefetch=no%explicit,那么显式预取将不会出现在可执行文件中。
仅当启用了自动预取时,使用 latx:factor 才有效。除非将 latx:factor 与 -xprefetch=auto,latx:factor 一起使用,否则它会被忽略。
显式预取只应在度量支持的特殊环境下使用。
因为编译器可以在众多计算机与应用程序间调整预取机制以获得最佳性能,所以仅当性能测试指示性能明显提高时,才应当使用 -xprefetch=latx:factor。假定的预取延迟在不同发行版本中是不同的。因此,无论何时切换到不同的发行版本,强烈建议重新测试延迟因子对性能的影响。
其中,a 是 [no%]indirect_array_access。
使用此选项可以确定编译器是否以为直接内存访问生成预取的方式,为由选项 -xprefetch_level 指示的循环生成间接预取。
如果不指定 -xprefetch_auto_type 的设置,编译器会将其设置为 -xprefetch_auto_type=no%indirect_array_access。
-xdepend、-xrestrict 和 -xalias_level 等选项会影响计算候选间接预取的主动性,进而影响因更好的内存别名歧义消除信息而自动插入间接预取的主动性。
可使用 -xprefetch_level=i 选项控制由 -xprefetch=auto 确定的自动插入预取指令的主动性。编译器变得更加主动,也就是说,引入更多预取级别 -xprefetch_level(依次增高)。
-xprefetch_level 取何适当值取决于应用程序的高速缓存未命中次数。-xprefetch_level 值越高,越有可能提高那些高速缓存未命中次数较多的应用程序的性能。
i 必须是 1、2 或 3,如下表所示。
表 A-42 -xprefetch_level 值
|
指定了 -xprefetch=auto 时,缺省值为 -xprefetch_level=1。
仅当使用 -xprefetch=auto 对该选项进行编译,优化级别为 3 或更高 (-xO3),而且是在支持预取的 64 位 SPARC 平台 (-m64) 上时,该选项才有效。
p 必须为 collect[:profdir]、use[:profdir] 或 tcov[:profdir]。
此选项可在执行期间收集并保存执行频率数据,然后在后续运行中可以使用该数据来改进性能。对多线程应用程序来讲,分析收集 (Profile collection) 是一种安全的方法。对执行自身多任务处理 (-mt) 的程序进行分析可产生准确的结果。只有指定 -xO2 或更高的优化级别时,此选项才有效。如果分别执行编译和链接,则链接步骤和编译步骤中必须都出现同一 -xprofile 选项。
在 -xprofile=use 时优化器收集并保存执行频率,以供将来使用。编译器生成可测量语句执行频率的代码。
-xMerge, -ztext, 和 -xprofile=collect 不应同时使用。-xMerge 会强制将静态初始化的数据存储到只读存储器中,-ztext 禁止在只读存储器中进行依赖于位置的符号重定位,而 -xprofile=collect 会在可写存储器中生成静态初始化的、依赖于位置的符号重定位。
分析目录名 profdir(如果指定)是包含已分析的目标代码的程序或共享库在执行时用来存储分析数据的目录路径名。如果 profdir 路径名不是绝对路径,在使用选项 -xprofile=use:profdir 编译程序时将相对于当前工作目录来解释该路径。
如果未使用 —xprofile=collect: prof_dir 或 —xprofile=tcov: prof_dir 指定分析目录名,分析数据将在运行时存储在名为 program.profile 的目录中,其中 program 是已分析的进程主程序的基本名称。在这种情况下,可以使用环境变量 SUN_PROFDATA 和 SUN_PROFDATA_DIR 控制在运行时存储分析数据的位置。如果已设置,分析数据将写入 $SUN_PROFDATA_DIR/$SUN_PROFDATA 指定的目录。如果在编译时指定了分析目录名,则 SUN_PROFDATA_DIR 和 SUN_PROFDATA 在运行时将无效。这些环境变量同样控制由 tcov 写入的分析数据文件的路径和名称,如 tcov(1) 手册页中所述。
如果未设置这些环境变量,分析数据将写入当前目录中的目录 profdir.profile,其中 profdir 是可执行文件的名称或在 -xprofile=collect: profdir 标志中指定的名称。如果 profdir 已在 .profile 中结束,-xprofile 不会将 .profile 附加到 profdir 中。如果多次运行程序,那么执行频率数据会累积在 profdir.profile 目录中;也就是说,以前执行的输出不会丢失。
如果在不同的步骤中进行编译和链接,应确保使用 -xprofile=collect 编译的任何目标文件也使用 -xprofile=collect 进行链接。
以下示例在生成程序所在目录的 myprof.profile 目录中收集分析数据,然后使用这些分析数据:
demo: CC -xprofile=collect:myprof.profile -xO5 prog.cc -o prog demo: ./prog demo: CC -xprofile=use:myprof.profile -xO5 prog.cc -o prog
以下示例在目录 /bench/myprof.profile 中收集分析数据,然后在优化级别为 -xO5 的反馈编译中使用收集的分析数据:
demo: CC -xprofile=collect:/bench/myprof.profile \ -xO5 prog.cc -o prog ...run prog from multiple locations.. demo: CC -xprofile=use:/bench/myprof.profile \ -xO5 prog.cc -o prog
通过从使用 —xprofile=collect[: profdir] 或 —xprofile=tcov[: profdir] 编译的代码中收集的执行频率数据,优化在执行已分析的代码时执行的工作。profdir 是一个目录的路径名,该目录包含运行用 —xprofile=collect[: profdir] 或 —xprofile=tcov[: profdir] 编译的程序所收集的分析数据。
要生成可供 tcov 和 —xprofile=use[:profdir] 使用的数据,必须在编译时通过选项 —xprofile=tcov[:profdir] 指定分析目录。必须在 —xprofile=tcov: profdir 和 —xprofile=use: profdir 中指定同一分析目录。为最大限度地减少混淆情况,请将 profdir 指定为绝对路径名。
profdir 路径名是可选的。如果未指定 profdir,将使用可执行二进制文件的名称。如果未指定 -o,将使用 a.out。如果未指定 profdir,编译器将查找 profdir.profile/feedback 或 a.out.profile/feedback。例如:
demo: CC -xprofile=collect -o myexe prog.cc demo: CC -xprofile=use:myexe -xO5 -o myexe prog.cc
程序是使用以前生成并保存在 feedback 文件中的执行频率数据优化的,此数据是先前执行用 -xprofile=collect 编译的程序时写入的。
除了 -xprofile 选项之外,源文件和其他编译器选项必须与用于编译(该编译过程创建了生成 feedback 文件的编译程序)的相应选项完全相同。编译器的相同版本必须同时用于 collect 生成和 use 生成。
如果用 -xprofile=collect:profdir 编译,则必须将相同的分析目录名 profdir 用在优化编译中:-xprofile=use: profdir。
另请参见 -xprofile_ircache,以了解有关加速 collect 阶段和 use 阶段之间的编译的说明。
如果指定可选的 profdir 参数,编译器将在指定位置创建分析目录。该分析目录中存储的数据可通过 tcov(1) 或由编译器通过 -xprofile=use:profdir 来使用。如果省略可选的 profdir 路径名,执行已进行分析的程序时将创建分析目录。只能通过 tcov(1) 使用该分析目录中存储的数据。使用环境变量 SUN_PROFDATA 和 SUN_PROFDATA_DIR 可以控制分析目录的位置。
如果 profdir 指定的位置不是绝对路径名,则在编译时将相对于编译时的当前工作目录来解释该位置。如果为任何目标文件指定了 profdir,则必须为同一程序中的所有目标文件指定同一位置。由 profdir 指定位置的目录必须在要执行已进行分析的程序的所有计算机中都可以访问。除非不再需要分析目录中的内容,否则不应删除该目录,因为除非重新编译,否则编译器存储在其中的数据将无法恢复。
如果用 -xprofile=tcov:/test/profdata 编译一个或多个程序的目标文件,编译器会创建一个名为 /test/profdata.profile 的目录并将其用来存储描述已进行分析的目标文件的数据。该同一目录还可在执行时用来存储与已进行分析的目标文件关联的执行数据。
如果名为 myprog 的程序使用 -xprofile=tcov 进行编译并在目录 /home/joe 中执行,将在运行时创建目录 /home/joe/myprog.profile 并将其用来存储运行时分析数据。
(仅限 SPARC)可以将 -xprofile_ircache[=path] 与 -xprofile=collect|use 一起使用,并重新使用 collect 阶段保存的编译数据,以改善 use 阶段的编译时间。
在编译大程序时,由于中间数据的保存,使得 use 阶段的编译时间大大减少。注意,所保存的数据会占用相当大的磁盘空间。
在使用 -xprofile_ircache[=path] 时,path 会覆盖保存缓存文件的位置。缺省情况下,这些文件会作为目标文件保存在同一目录下。collect 和 use 阶段出现在两个不同目录中时,指定路径很有用。以下示例显示了典型的命令序列:
example% CC -xO5 -xprofile=collect -xprofile_ircache t1.cc t2.cc example% a.out // run collects feedback data example% CC -xO5 -xprofile=use -xprofile_ircache t1.cc t2.cc
(仅限 SPARC)使用 -xprofile_pathmap= collect-prefix:use-prefix 选项(同时还指定 -xprofile=use 命令)。以下两个条件都成立且编译器无法找到使用 -xprofile=use 编译的目标文件的分析数据时,使用 -xprofile_pathmap。
使用 -xprofile=use 编译目标文件所在的目录与先前使用 -xprofile=collect 编译目标文件所在的目录不同。
目标文件在分析中共享公共基名,但可以根据它们在不同目录中的位置互相区分。
collect-prefix 是某个目录树的 UNIX 路径名的前缀,该目录树中的目标文件是使用 -xprofile=collect 编译的。
use-prefix 是目录树的 UNIX 路径名的前缀,该目录树中的目标文件是使用 -xprofile=use 编译的。
如果指定了 -xprofile_pathmap 的多个实例,编译器将按照这些实例的出现顺序对其进行处理。将 -xprofile_pathmap 实例指定的每个 use-prefix 与目标文件路径名进行比较,直至找到匹配的 use-prefix 或发现最后一个指定的 use-prefix 与目标文件路径名也不匹配。
对自动并行化中的约简进行循环分析。只有在同时指定了 -xautopar 时,此选项才有效。否则,编译器会发出警告。
当启用了约简识别时,编译器会并行化约简,例如点积、最大与最小查找。这些约简产生的舍入与通过非并行化代码获得的舍入不同。
r 是一个逗号分隔列表,它包含下面的一个或多个子选项:appl、float、frameptr。
用 no% 作为子选项的前缀会禁用该子选项。例如:-xregs=appl,no%float
请注意,-xregs 子选项仅限于特定的硬件平台。
表 A-43 -xregs 子选项
|
SPARC 缺省值为 -xregs=appl,float。
x86 缺省值为 -xregs=no%frameptr。
在 x86 系统中,-xpg 与 -xregs=frameptr 不兼容,这两个选项不应一起使用。还请注意,-fast 中包括 -xregs=frameptr。
对于打算供将链接到应用程序的共享库使用的代码,应当使用 -xregs=no%appl,float 进行编译。至少共享库应该显式说明它如何使用应用程序寄存器,以便与这些库链接的应用程序知道这些寄存器分配。
例如,在某种全局意义上使用寄存器(例如,使用寄存器指向一些关键数据结构)的应用程序,需要确切地知道其代码未使用 -xregs=no%appl 编译的某个库如何使用应用程序寄存器,以便安全地与该库链接。
将赋值为指针的函数参数视为受限指针。f 必须是下表中列出的值之一:
表 A-44 -xrestrict 值
|
此命令行选项可以单独使用,但最好将其用于优化。
例如,以下命令将文件 prog.c 中的所有指针参数都视为受限指针。
%CC -xO3 -xrestrict=%all prog.cc
以下命令将文件 prog.c 中的函数 agc 中的所有指针参数都视为受限指针:
%CC -xO3 -xrestrict=agc prog.cc
注意,虽然 C 编程语言的 C99 标准引入了 restrict 关键字,但此关键字并不属于当前 C++ 标准。某些编译器具有针对 C99 restrict 关键字的 C++ 语言扩展,有时拼写为 __restrict 或 __restrict__。但 Oracle Solaris Studio C++ 编译器当前没有该扩展。-xrestrict 选项是源代码中 restrict 关键字的部分替代。(使用该关键字后,并非函数的所有指针参数都需要声明为 restrict。)关键字主要影响优化机会,还会限制可以传递给函数的参数。从源代码中删除 restict 或 __restrict 的所有实例不会影响程序的可观测行为。
缺省值为 %none;指定 -xrestrict 与指定 -xrestrict=%source 等效。
为使编译器高效并行执行循环,需要确定某些左值是否指定不同的存储区域。别名是其存储区域相同的左值。由于需要分析整个程序,因此确定对象的两个指针是否为别名是一个困难而费时的过程。请考虑以下示例中的函数 vsq():
extern "C" void vsq(int n, double *a, double *b) { int i; for (i=0; i<n; i++) { b[i] = a[i] * a[i]; } }
如果编译器知道指针 a 和 b 访问不同的对象,可以并行化循环的不同迭代的执行。如果通过指针 a 和 b 访问的对象存在重叠,编译器以并行方式执行循环将会不安全。
在编译时,编译器并不能通过简单地分析函数 vsq() 来获悉 a 和 b 访问的对象是否重叠。编译器可能需要分析整个程序才能获取此信息。可以使用以下命令行选项指定将赋值为指针的函数参数视为受限指针:-xrestrict[=func1,...,funcn]。如果指定了函数列表,则指定函数中的指针参数被视为受限的。否则,整个源文件中的所有指针参数都会被视为受限的(不推荐)。例如,-xrestrict=vsq 限定 vsq() 函数示例中给定的指针 a 和 b。
将指针参数声明为限定的表示指针指定不同的对象。编译器可以假定 a 和 b 指向不同的存储区域。有了此别名信息,编译器就能够并行化循环。
请确保正确使用 -xrestrict。如果指针被限定为指向并非不同的对象的限定指针,编译器可能会错误地并行化循环,从而导致不确定的行为。例如,假定函数 vsq() 的指针 a 和 b 指向的对象重叠,如 b[i] 和 a[i+1] 是同一对象。如果 a 和 b 未声明为限定指针,循环将以串行方式执行。如果 a 和 b 被错误地限定为受限指针,编译器可能会并行化循环的执行,这是不安全的,因为 b[i+1] 仅应在计算 b[i] 之后进行计算。
允许 dbx 在没有目标 (.o) 文件的情况下进行调试。
该选项导致所有调试信息被复制到可执行程序中。此选项对程序的 dbx 性能和运行时性能影响很小,但占用很大的磁盘空间。
该选项只有在 -xdebugformat=stabs 时才有效,缺省情况下不将调试数据复制到可执行文件。使用缺省调试格式 -xdebugformat=dwarf 时,总是将调试数据复制到可执行文件,没有选项可以阻止复制。
(仅限 SPARC)允许编译器假定不会发生任何内存保护违规。
该选项允许编译器使用 SPARC V9 架构中的无故障装入指令。
仅当与优化级别 -xO5 及以下 -xarch 值中的一个一起使用时,此选项才能有效:sparc、sparcvis、sparcvis2 或 sparcvis3(用于 -m32 和 -m64)。
由于在发生诸如地址未对齐或段违规的故障时,无故障装入不会导致陷阱,因此您应该只对不会发生此类故障的程序使用该选项。因为只有很少的程序会导致基于内存的陷阱,所以您可以安全地将该选项用于大多数程序。对于显式依赖基于内存的自陷来处理异常情况的程序,请勿使用该选项。
通过为编译器提供目标计算机硬件的精确描述,某些程序的性能可得到提高。当程序性能很重要时,目标硬件的正确指定是非常重要的。在较新的 SPARC 处理器上运行时,尤其是这样。不过,对大多数程序和较旧的 SPARC 处理器来讲,性能的提高微不足道,因此指定 generic 就足够了。
t 的值必须是下列值之一: native、generic、native64、generic64 或 system-name。
-xtarget 的每个特定值都会扩展到 -xarch、-xchip 和 -xcache 选项值的特定集合。使用 -xdryrun 选项可在运行的系统上确定 -xtarget=native 的扩展。
例如,-xtarget=ultraT2 等效于 -xarch=sparcvis2 -xchip=ultraT2-xcache=8/16/4:4096/64/16。
注 - -xtarget 在特定主机平台上的扩展在该平台上编译时扩展到的 -xarch、-xchip 或 -xcache 设置可能与 -xtarget=native 不同。
本节按平台提供 -xtarget 值的说明。下表列出了所有平台的 -xtarget 值。
表 A-45 -xtarget 值(所有平台)
|
在 SPARC 还是 UltraSPARC V9 上针对 64 位 Solaris 软件进行编译,是由 -m64 选项指示。如果指定带有 native64 或 generic64 之外的标志的 -xtarget,还必须指定 -m64 选项,如下所示:-xtarget=ultra... -m64。否则,编译器将使用 32 位内存模型。
表 A-46 SPARC 体系结构上的 -xtarget 扩展
|
在 64 位 x86 平台上针对 64 位 Solaris 软件进行编译是由 -m64 选项指示的。如果为 -xtarget 指定 native64 或 generic64 以外的标志,则还必须按如下所示指定 -m64 选项:-xtarget=opteron ... -m64。否则,编译器将使用 32 位内存模型。
表 A-47 -xtarget 值(x86 平台)
|
在 SPARC 和 x86 设备上,如果未指定 –xtarget,则假定 –xtarget=generic。
–xtarget 选项是一个宏,使用它可以快捷地指定可在从市场上购买的平台上使用的 -xarch、–xchip 和 –xcache 组合。–xtarget 的唯一含义在其扩展中。
-xtarget=ultra 表示 -xchip=ultra -xcache=16/32/1:512/64/1 -xarch=sparcvis。
针对 64 位 SPARC V9 体系结构的编译由 -m64 选项指示。不必设置 –xtarget=ultra 或 ultra2,而且这也不够。如果指定了 -xtarget,则对 —xarch、—xchip 或 —xcache 值所做的任何更改都必须位于 -xtarget 之后。例如:
–xtarget=ultra3 -xarch=ultra
在不同的步骤中进行编译和链接时,必须在编译步骤和链接步骤中使用相同的 -xtarget 设置。
指定 -xthreadvar 来控制线程局部变量的实现。将此选项与 __thread 声明说明符结合使用,可利用编译器的线程局部存储功能。使用 __thread 说明符声明线程变量后,请指定 -xthreadvar,以便能够将线程局部存储用于动态(共享)库中的位置相关的代码(非 PIC 代码)。有关如何使用 __thread 的更多信息,请参见4.2 线程局部存储。
下表列出了 o 的可能值。
表 A-48 -xthreadvar 值
|
如果未指定 -xthreadvar,则编译器所用的缺省设置取决于是否启用与位置无关的代码。如果启用了与位置无关的代码,则该选项设置为 -xthreadvar=dynamic。如果禁用了与位置无关的代码,则该选项设置为 -xthreadvar=no%dynamic。
如果指定了 -xthreadvar 但未指定任何参数,则该选项设置为 -xthreadvar=dynamic。
编译和链接使用 __thread 的文件时,必须使用 -mt 选项。
如果动态库包含与位置无关的代码,则必须指定 -xthreadvar。
链接程序不支持在动态库中与非 PIC 代码等效的线程变量。由于非 PIC 线程变量要快很多,所以应将其用作可执行文件的缺省设置。
-xcode、-KPIC 和 -Kpic
启用或禁用对 ISO/ANSI C 标准定义的三字母序列的识别。
如果源代码具有包含问号 ( ?) 的文字串(编译器将其解释为三字符序列),那么您可以使用 -xtrigraph=no 子选项禁用对三字符序列的识别。
下面列出了 -xtrigraphs 的可能值。
表 A-49 -xtrigraphs 值
|
如果没有在命令行上指定 -xtrigraphs 选项,则编译器假定 -xtrigraphs=yes。
如果仅指定了 -xtrigraphs,则编译器假定 -xtrigraphs=yes。
请考虑以下名为 trigraphs_demo.cc 的示例源文件。
#include <stdio.h> int main () { (void) printf("(\?\?) in a string appears as (??)\n"); return 0; }
以下示例显示了使用 -xtrigraphs=yes 编译此代码时的输出。
example% CC -xtrigraphs=yes trigraphs_demo.cc example% a.out (??) in a string appears as (]
以下示例显示了使用 -xtrigraphs=no 编译此代码时的输出。
example% CC -xtrigraphs=no trigraphs_demo.cc example% a.out (??) in a string appears as (??)
有关三字母的信息,请参见《C 用户指南 》中关于转换到 ANSI/ISO C 的章节。
此选项指示编译器通过解开循环(如有可能)来优化这些循环。
n 为 1 时,建议编译器不要解开循环。
n 为大于 1 的整数(-unroll=n)时,编译器会将循环解开 n 次。
如果代码中包含要编译器转换成目标文件中 UTF-16 字符串的字符串或字符文字,可以使用该选项。如果不指定该选项,编译器既不生成、也不识别 16 位的字符串文字。使用该选项时,U"ASCII-string" 字符串文字会识别为无符号短整型数组。因为这样的字符串还不属于任何标准,所以该选项的作用是使非标准 C++ 得以识别。
不是所有文件都必须使用该选项编译。
如果需要支持使用 ISO10646 UTF-16 文本字符串的国际化应用程序,可指定 -xustr=ascii_utf16_ushort。可以通过指定 -xustr=no 来禁用编译器对 U"ASCII_string" 字符串或字符文字的识别。该选项在命令行上最右侧的实例覆盖了先前的所有实例。
可以指定 -xustr=ascii_ustf16_ushort,而无需同时指定 U"ASCII-string" 字符串文字。这样执行时不会出现错误。
缺省值为 -xustr=no。如果指定了没有参数的 -xustr,编译器将不接受该选项,而是发出一个警告。如果 C 或 C++ 标准定义了语法的含义,那么缺省设置是可以更改的。
以下示例显示了前置有 U 的带引号文本字符串。它还显示指定 -xustr 的命令行。
example% cat file.cc const unsigned short *foo = U"foo"; const unsigned short bar[] = U"bar"; const unsigned short *fun() {return foo;} example% CC -xustr=ascii_utf16_ushort file.cc -c
8 位字符文字可以带有 U 前缀,以形成一个 unsigned short 类型的 16 位 UTF-16 字符。例如:
const unsigned short x = U'x'; const unsigned short y = U'\x79';
启用向量库函数调用自动生成,或在支持 SIMD(Single Instruction Multiple Data,单指令多数据)的 x86 处理器上启用 SIMD 指令生成。使用此选项时,必须通过指定 -fround=nearest 来使用缺省的舍入模式。
-xvector 选项需要 -xO3 或更高的优化级别。如果优化级别未指定或低于 -xO3,编译将不会继续,同时会发出消息。
下表列出了 a 的可能值。no% 前缀可禁用关联的子选项。
表 A-50 -xvector 子选项
|
在 x86 平台上的缺省值为 -xvector=simd,在 SPARC 平台上的缺省值为 -xvector=%none。如果指定不带子选项的 -xvector,在 x86 Solaris、SPARC Solaris 和 Linux 平台上,编译器将分别采用 -xvector=simd,lib、-xvector=lib 和 -xvector=simd。
在装入步骤中,编译器包含 libmvec 库。
如果使用单独的命令进行编译和链接,应确保也在链接 CC 命令中使用 -xvector。
(仅限 SPARC)在使用 VIS 软件开发者工具包 (VIS Software Developers Kit, VSDK) 中定义的汇编语言模板时,或使用采用了 VIS 指令和 vis.h 头文件的汇编程序内联代码时,请使用 -xvis=[ yes|no] 命令。
VIS 指令集是 SPARC v9 指令集的扩展。尽管 UltraSPARC 是 64 位处理器,但在很多情况下数据都限制在 8 位或 16 位范围内,特别是多媒体应用程序中。VIS 指令可以用一条指令处理四个 16 位数据,这个特性使得处理诸如图像、线性代数、信号处理、音频、视频以及网络等新媒体的应用程序的性能大大提高。
缺省值为 -xvis=no。指定 -xvis 与指定 -xvis=yes 等效。
发出关于并行编程相关的潜在问题的警告,在使用 OpenMPI 时这些问题可能会导致不正确的结果。与 -xopenmp 和 OpenMP API 指令一起使用。
编译器在检测到下列情形时会发出警告。
循环是使用 MP 指令并行化的,而这些指令中的不同循环迭代之间存在数据依赖性
OpenMP 数据共享属性子句存在问题。例如,声明在 OpenMP 并行区域中的访问可能导致数据争用的变量 "shared",或者声明其在并行区域中的值在并行区域之后使用的变量 "private"。
如果所有并行化指令在处理期间均未出现问题,则不显示警告。
注 - Solaris Studio 编译器支持 OpenMP API 并行化。因此,已废弃 MP pragma 指令,不再支持此类指令。有关迁移到 OpenMP API 的信息,请参见《OpenMP API 用户指南》。
通过返回非零的退出状态,将所有警告转换成错误。
指定组件 c 的位置的新路径。
如果已指定组件的位置,则组件的新路径名称为 path/component-name。该选项传递给 ld。
下表列出了 c 的可能值。
表 A-51 -Y 标志
|
可以在命令行上指定多个 -Y 选项。如果对任何一个组件应用了多个 -Y 选项,则保留最后一个选项。
Solaris《链接程序和库指南》