本节简要介绍在 Sun Studio 12 C++ 5.9 编译器发行版中引入的 C 编译器的新特性和新功能。有关详细的说明,请参见每项的交叉引用。
现在,可以在以下 Linux 分发(x86 和 x64)上使用 C 编译器:
带有 Service Pack 3 的 SuSE Linux Enterprise Server 9(或更高版本)。
Red Hat Enterprise Linux 4。
其他基于 2.6 内核的 Linux 分发(尽管它们不受官方支持)。
决定内存模型的新 -m32|-m64 选项。
新的 -xarch 标志替换了过时的标志。
-xtarget 和 -xchip 的新值为 UltraSPARC T2 和 SPARC64vi 处理器提供代码生成。
新标志 -fma=fused 可在受支持的处理器上启用生成乘加指令。
在 x86 和 SPARC 平台上接受显式预取宏。(-xprefetch=explicit)
在本发行版中,指定 32 位或 64 位二进制的编译的方式已更改。A.2.107 –xarch=isa 选项不再采取隐式内存模式(32 位 ILP32 或 64 位 LP64,使用其各自定义),现在仅用于指定目标处理器的指令集。
请使用新的A.2.50 -m32|-m64选项来指定目标编译的内存模型。
ILP32 模型指定 C 语言的 int、long 和指针数据类型的宽度都是 32 位。LP64 模型指定 long 和指针数据类型的宽度都是 64 位。Solaris 和 Linux OS 还支持 LP64 内存模型下的大型文件和大型数组。
如果使用 -m64 编译,则生成的可执行文件仅能在运行 64 位内核的 Solaris OS 或 Linux OS 下的 64 位 UltraSPARC(R) 或 x86 处理器上运行。64 位对象的编译、链接和执行只能在支持 64 位执行的 Solaris 或 Linux OS 上进行。
针对 x86 Solaris 平台进行编译时,有一些重要问题需要了解。
传统的 Sun 样式并行化 pragma 在 x86 上不可用,而改用 OpenMP。有关将传统并行化指令转换为 OpenMP 的信息,请参见《Sun Studio 12: OpenMP API User’s Guide》。
如果编译程序时将 -xarch 设置为 sse、sse2、sse2a 或 sse3,则这些程序必须仅在提供这些扩展和功能的平台上运行。
从 Solaris 9 4/04 开始的 Solaris OS 发行版在 Pentium 4 兼容的平台上启用了 SSE/SSE2。早期版本的 Solaris OS 未启用 SSE/SSE2。如果运行的 Solaris OS 中未启用由 -xarch 选择的指令集,编译器将无法为该指令集生成或链接代码。
如果在不同的步骤中进行编译和链接,请始终使用编译器和相同的 -xarch 设置进行链接,以确保链接正确的启动例程。
在 x86 上得到的数值结果可能与在 SPARC 上得到的结果不同,这是由 x86 80 位浮点寄存器造成的。为了最大限度减少这些差异,请使用 -fstore 选项或使用 x-arch=sse2 进行编译(如果硬件支持 SSE2)。
Solaris 和 Linux 的数值结果也可能不同,因为内部数学库(如 sin(x))并不相同。
从 Sun Studio 11 和 Solaris 10 OS 开始,会对使用这些专用的 -xarch 硬件标志编译和生成的程序二进制文件进行验证,看其是否在适当的平台上运行。
在 Solaris 10 之前的系统中,不执行任何验证,用户负责确保使用这些标志生成的对象部署在合适的硬件上。
如果在没有相应功能或指令集扩展的平台上运行使用这些 -xarch 选项编译的程序,则可能会导致段故障或不正确的结果,并且不显示任何显式警告消息。
此警告还适用于使用利用 SSE、SSE2、SSE2a 和 SSE3 指令和扩展的 .il 内联汇编语言函数或 __asm() 汇编程序代码。
C++ 编译器 (CC) 支持 C++ ISO 国际标准 ISO IS 14882:1998,编程语言-C++。当前发行版本附带的自述文件描述了与标准需求的所有差异。
在 SPARCTM 平台上,编译器提供了对 SPARC V8 和 SPARC V9(包括 UltraSPARCTM 实现)优化开发功能的支持。在 Prentice-Hall for SPARC International 发行的第 8 版 (ISBN 0-13-825001-4) 和第 9 版 (ISBN 0-13-099227-5) SPARC Architecture Manual 中定义了这些功能。
在本文档中,“标准”是指与上面列出的标准版本相一致。“非标准”或“扩展”是指这些标准的这些版本之外的功能。
负责标准的一方可能会不时地修订这些标准。C++ 编译器兼容的适用标准版本可能被修订或替换,这将会导致以后的 Sun C++ 编译器发行版本在功能上与旧的发行版本产生不兼容。
C++ 编译器的自述文件列出了关于编译器的重要信息,其中包括:
在手册印刷之后发现的信息
新特性和更改的特性
软件更正
问题和解决办法
限制和不兼容
可发送库
未实现的标准
要查看 C++ 自述文件的文本格式文件,请在命令提示符后输入以下命令:
example% CC -xhelp=readme |
要访问此自述文件的 HTML 版本,请在 Netscape Communicator4.0 或兼容版本的浏览器中打开以下文件:
/opt/SUNWspro/docs/index.html
(如果您的 C++ 编译器软件没有安装在 /opt 目录中,请通过系统管理员获取您系统中的等效路径。)浏览器可以显示 HTML 文档的索引。要打开自述文件,请在索引中找到其对应条目,然后单击标题。
联机手册 (man) 页提供了关于命令、函数、子例程以及收集这些信息的文档。
可以通过运行以下命令来显示手册页:
example% man topic |
在整个 C++ 文档中,手册页参考以主题名称和手册节编号显示:CC(1) 通过 man CC 进行访问。例如,可在 man 命令中使用 -s 选项来访问 ieee_flags(3M) 指示的其他部分:
example% man -s 3M ieee_flags |
以下 C++ 实用程序现已并入传统的 UNIX® 工具并且与 UNIX 操作系统捆绑在了一起:
lex-生成用于文本简单词法分析的程序
yacc-根据语法生成 C 函数分析输入流
prof-生成程序模块的执行配置文件
gprof-按过程来配置程序运行时性能
tcov-按语句来配置程序运行时性能
有关这些 UNIX 工具的详细信息,请参见《 Program Performance Analysis Tools》和相关手册页。
此发行版本的 C++ 支持使用英语以外的其他语言进行应用程序的开发,包括了大多数欧洲语言和日语。因此,您可以十分便捷地将应用程序从一种语言切换到另一种语言。此功能被称为国际化。
通常,C++ 编译器按如下方式实现国际化:
C++ 从国际化的键盘识别 ASCII 字符(也就是说,它具有键盘独立性和 8 位清除)。
C++ 允许使用本地语言打印某些消息。
C++ 允许在注释、字符串和数据中使用本地语言。
C++ 只支持符合扩展 UNIX 字符 (Extended UNIX Characte, EUC) 的字符集,在该字符集中,字符串内每个空字节是一个空字符,而字符串内每个 ascii 值为 "/" 的字节是一个 "/" 字符。
变量名称不能国际化,必须使用英文字符集。
您可以设置语言环境将应用程序从一种本地语言更改为另一种语言。关于这一点和其他本地语言支持功能的信息,请参见操作系统文档。
本章描述了如何使用 C++ 编译器。
任何编译器的主要用途是将高级语言(如 C++)编写的程序转换成目标计算机硬件可执行的数据文件。您可以使用 C++ 编译器完成以下任务:
将源文件转换成可重定位的二进制 (.o) 文件(以后链接到可执行文件)、静态(归档)库 (.a) 文件(使用 – xar)或动态(共享)库 (.so) 文件中
将目标文件或库文件(或两者)链接或重链接成可执行文件
在运行时调试处于启用状态的情况下编译可执行文件 (-g)
使用运行时语句或过程级文件配置 (-pg) 编译可执行文件
本节简要概述了如何使用 C++ 编译器编译和运行 C++ 程序。有关命令行选项的完整参考,请参见16.8 使用 dlopen 从 C 程序访问 C++ 库。
本章中的命令行示例说明了 CC 的用法。打印输出可能会稍有不同。
生成和运行 C++ 程序的基本步骤包括:
使用编辑器创建 C++ 源文件(后缀为表 2–1 中所列有效后缀之一)
调用编译器来生成可执行文件
通过输入可执行文件的名称来启动程序
以下程序在屏幕上显示消息:
example% cat greetings.cc #include <iostream> int main() { std::cout << “Real programmers write C++!” << std::endl; return 0; } example% CC greetings.cc example% a.out Real programmers write C++! example% |
在此示例中, CC 编译源文件 greetings.cc,并且在缺省情况下编译可执行程序生成文件 a.out。要启动该程序,请在命令提示符下键入可执行文件的名称 a.out。
传统的方法是,UNIX 编译器为可执行文件命名 a.out。每次编译都写入到同一个文件是比较笨拙的方法。另外,如果已经有这样一个文件存在,下次运行编译器时该文件将被覆盖。因此,改用 -o 编译器选项来指定可执行输出文件的名称,如以下示例所示:
example% CC– o greetings greetings.cc |
在此示例中,-o 选项通知编译器将可执行代码写入文件 greetings。(由单独源文件组成的程序通常提供无后缀的源文件名称。)
也可以在每次编译后使用 mv 命令来为缺省的 a.out 文件重命名。无论是哪种方法,都可以通过键入可执行文件的名称来运行程序:
example% greetings Real programmers write C++! example% |
本章其余部分讨论了 CC 命令使用的约定、编译器源代码行指令和其他有关编译器的使用问题。
CC [options] [source-files] [object-files] [libraries] |
选项是前缀为短划线 (–) 或加号 (+) 的选项关键字。某些选项带有参数。
通常,编译器选项的处理顺序是从左到右,从而允许有选择地覆盖宏选项(包含其他选项的选项)。在大多数的情况下,如果您多次指定同一个选项,那么最右边的赋值会覆盖前面的赋值,而不会累积。注意以下特殊情况:
所有链接程序选项和 -features、–I -l、– L、-library、–pti、–R、-staticlib、-U、-verbose、-xdumpmacros 和 -xprefetch 选项都会累积,但它们不会覆盖。
所有 –U 选项都在所有 –D 选项后处理。
源文件、目标文件和库按它们在命令行上出现的顺序编译并链接。
在以下示例中,在启用了运行时调试的情况下使用 CC 编译两个源文件(growth.C 和 fft.C)以生成名为 growth 的可执行文件:
example% CC -g -o growth growth.C fft.C |
命令行上附加在文件名后面的后缀确定了编译器处理文件的方式。如果文件名称的后缀没有在下表中列出,或文件名称没有后缀,那么都要传递到链接程序。
表 2–1 C++ 编译器识别的文件名称后缀
后缀 |
语言 |
操作 |
---|---|---|
C++ |
以 C++ 源文件编译,将目标文件放在当前目录中;目标文件的缺省名称是源文件名称加上 .o 后缀。 |
|
C++ |
操作与 .c 后缀相同。 |
|
C++ |
操作与 .c 后缀相同。 |
|
C++ |
操作与 .c 后缀相同。 |
|
C++ |
操作与 .c 后缀相同。 |
|
C++ |
操作与 .c 后缀相同。 |
|
C++ |
将预处理程序输出文件作为 C++ 源文件处理。操作与 .c 后缀相同。 |
|
汇编程序 |
使用汇编程序的汇编源文件。 |
|
汇编程序 |
使用 C 语言预处理程序和汇编程序的汇编源文件。 |
|
内联扩展 |
处理内联扩展的汇编内联模板文件。编译器将使用模板来扩展选定例程的内联调用。(内联模板文件是特殊的汇编文件。请参见 inline(1) 手册页。) |
|
目标文件 |
将目标文件传递到链接程序。 |
|
静态(归档)库 |
将目标库名传递到链接程序。 |
|
动态(共享)库 |
将共享对象的名称传递到链接程序。 |
C++ 编译器在命令行上接受多个源文件。编译器编译的单个源文件和其直接或间接支持的任何文件一起统称为编译单元。C++ 将每个源作为一个单独的编译单元处理。
从 C++ 5.1 编译器开始,编译器为模板高速缓存目录标记用于标识模板高速缓存版本的字符串。
此编译器在缺省情况下不使用缓存。只有指定了 -instances=extern 时,它才使用高速缓存。如果编译器使用高速缓存,它会检查高速缓存目录的版本,并在遇到高速缓存版本问题时发出错误消息。以后的 C++ 编译器也会检查缓存的版本。例如,具有不同模板缓存版本标识的未来版本编译器在处理此发行版本的编译器生成的缓存目录时,会发出与以下消息类似的错误:
Template Database at ./SunWS_cache is incompatible with this compiler |
编译器遇到新版本的编译器生成的缓存目录时,也会发出类似的错误。
虽然未使用版本标识符标记由 C++ 5.0 编译器生成的模板缓存目录,但当前编译器在处理 5.0 缓存目录时不会出现错误或警告。编译器将 5.0 缓存目录转换为编译器使用的目录格式。
C++ 5.0 编译器不能使用新版本编译器生成的缓存目录。C++ 5.0 编译器不能识别格式差异,并在遇到由 C++ 5.1 或新版本编译器生成的缓存目录时将会发出断言。
升级编译器时,最好清除缓存。可对包含模板高速缓存目录(大多数情况下,模板高速缓存目录名为 SunWS_cache))的每个目录运行 CCadmin -clean。也可以使用 rm -rf SunWS_cache。
本节描述了编译和链接程序的某些方面。在以下示例中,使用 CC 编译三个源文件并链接目标文件以生成名为 prgrm 的可执行文件。
example% CC file1.cc file2.cc file3.cc -o prgrm |
在前面的示例中,编译器会自动生成加载器目标文件(file1.o、file2.o 和 file3.o),然后调用系统链接程序来为 prgrm 文件创建可执行程序。
编译后,目标文件(file1.o、file2.o 和 file3.o)仍保留不变。此约定让您易于重新链接和重新编译文件。
如果只编译了一个源文件,且在同一个操作中链接了程序,则对应的 .o 文件将会被自动删除。要保留所有 .o 文件,就不要在同一个操作中进行编译和链接,除非编译多个源文件。
如果编译失败,您将收到每个错误的对应消息。对于那些出现错误的源文件,不会生成 .o 文件,也不会生成可执行程序。
可以在不同的步骤中进行编译和链接。如果使用 -c 选项,将编译源文件并生成 .o 目标文件,但不创建可执行文件。如果不使用 -c 选项,编译器将调用链接程序。通过将编译和链接步骤分开,仅修复一个文件就不需要完整重新编译。以下示例显示了如何以独立的步骤编译一个文件并与其他文件链接:
example% CC -c file1.cc Make new object file example% CC -o prgrm file1.o file2.o file3.o Make executable file |
请确保链接步骤列出了生成完整程序所需的全部目标文件。如果在此步骤中缺少任何目标文件,链接将会失败,并出现 "undefined external reference" 错误(缺少例程)。
如果在不同的步骤中进行编译和链接,则使用以下编译器选项时,一定要在编译和链接中保持一致:
-B
-compat
–fast
-g
-g0
-library
-misalign
-mt
-p
-xa
-xarch
–xcg92 和 -xcg89
-xipo
-xpagesize
-xpg
-xprofile
-xtarget
如果使用其中任何选项编译子程序,请确保在链接时也要使用相同的选项:
如果使用 -library、-fast、-xtarget 和 -xarch 选项,必须确保包括相应的链接程序选项,如果编译和链接同时进行的话,就可以忽略这些链接程序选项。
如果使用 -p、-xpg 和 -xprofile,则在一个阶段中包括选项而在其他阶段中不包括相应选项并不影响程序的正确性,但不能进行文件配置。
如果使用 -g 和 -g0,则在一个阶段中包括选项而在其他阶段中不包括相应选项并不影响程序的正确性,但会影响调试程序的能力。对于没有使用其中任一选项编译但使用 -g 或 -g0 链接的模块,将无法正确调试。请注意,要对包含函数 main 的模块进行调试,通常必须使用 -g 选项或 -g0 选项对其进行编译。
在以下示例中,使用 -xcg92 编译器选项编译程序。此选项是包含了 -xtarget=ss1000 的宏,扩展为: -xarch=v8 -xchip=super -xcache=16/64/4:1024/64/1。
example% CC -c -xcg92 sbr.cc example% CC -c -xcg92 smain.cc example% CC -xcg92 sbr.o smain.o |
如果程序使用模板,某些模板可以在链接时实例化。在这种情况下,来自最后一行(链接行)的命令行选项将用于编译实例化的模板。
只有在运行 64 位内核的 V9 SPARC Solaris 8 操作系统中才支持 64 位对象的编译、链接和执行。针对 64 位的编译通过 –xarch=v9、–xarch=v9a 和 -xarch=v9b 选项指明。
可以使用 –verbose 选项选项在编译程序时显示有用信息,例如调用的程序的名称和版本号以及每个编译阶段的命令行。
命令行上编译器无法识别的任何参数都解释为链接程序选项、目标程序文件名或库名称。
基本区别是:
对于无法识别的非选项(即前面没有短划线或加号),不会生成警告。(然而,这些选项会传递到链接程序。如果链接程序无法识别它们,将会生成链接程序错误消息。)
在以下示例中,请注意,CC 无法识别 -bit,该选项传递给链接程序 (ld),它会尝试解释该选项。因为一个字母的 ld 选项可以连在一起,所以链接程序将 -bit 视为 -b -i -t,所有这些都是合法的 ld 选项。这可能并不是您所希望看到的结果:
example% CC -bit move.cc < - -bit is not a recognized CC option CC: Warning: Option -bit passed to ld, if ld is invoked, ignored otherwise |
在下一个示例中,用户本想键入 CC 选项 -fast,但遗漏了前导短划线。编译器又一次将参数传递到链接程序,而链接程序将参数解释为文件名称:
example% CC fast move.cc < - The user meant to type -fast move.CC: ld: fatal: file fast: cannot open file; errno=2 ld: fatal: File processing errors. No output written to a.out |
C++ 编译器软件包由前端、优化器、代码生成器、汇编程序、模板预链接程序和链接编辑器组成。CC 命令会自动调用其中每个组件,除非使用命令行选项进行其他指定。
因为这些组件中的任何一个都可能生成错误,并且各个组件执行不同的任务,所以标识生成错误的组件是有意义的。可使用 -v 和 -dryrun 选项帮助解决此问题。
正如下表所示,不同编译器组件的输入文件拥有不同的文件名后缀。后缀建立了要进行的编译类型。有关文件后缀的含义,请参阅表 2–1。
表 2–2 C++ 编译系统的组件
组件 |
说明 |
使用说明 |
---|---|---|
前端(编译器预处理程序和编译器) | ||
SPARC:代码优化器 |
-xO[2-5], -fast |
|
x86:中间语言转换器 |
-xO[2-5], -fast |
|
SPARC:汇编语言模板的内联扩展 |
指定 .il 文件 |
|
x86:过程间的分析器 |
-xcrossfile=1,并使用 -xO4、-xO5 或 -fast |
|
汇编程序 | ||
SPARC:代码生成器、内联函数、汇编程序 |
|
|
ube |
x86:代码生成器 |
-xO[2-5], -fast |
模板预链接程序 | ||
非递增式链接编辑器 |
本节讨论了关于预处理 C++ 编译器所特有的指令的信息。
预处理程序关键字 pragma 是 C++ 标准的一部分,但每个编译器中,pragma 的形式、内容和含义都是不相同。有关 C++ 编译器可识别的 pragma 列表,请参见A.2.182 -z[ ]arg。
C++ 编译器接受以下形式的 #define 预处理程序指令。
#define identifier (...) replacement_list #define identifier (identifier_list, ...) replacement_list |
如果列出的宏参数以省略号结尾,那么该宏的调用允许使用除了宏参数以外的其他更多参数。其他参数(包括逗号)收集到一个字符串中,宏替换列表中的名称 __VA_ARGS__ 可以引用该字符串。以下示例说明了如何使用可变参数列表的宏。
#define debug(...) fprintf(stderr, __VA_ARGS__) #define showlist(...) puts(#__VA_ARGS__) #define report(test, ...) ((test)?puts(#test):\ printf(__VA_ARGS__)) debug(“Flag”); debug(“X = %d\n”,x); showlist(The first, second, and third items.); report(x>y, “x is %d but y is %d”, x, y); |
其结果如下:
fprintf(stderr, “Flag”); fprintf(stderr, “X = %d\n”, x); puts(“The first, second, and third items.”); ((x>y)?puts(“x>y”):printf(“x is %d but y is %d”, x, y)); |
附录中的表 A–2 介绍了预定义的宏。可以在 #ifdef 这样的预处理程序条件中使用这些值。+p 选项可防止自动定义 sun、unix、sparc 和 i386 预定义宏。
发出警告后,#error 指令不再继续编译。指令原来的行为是发出警告并继续编译。其新行为(和其他编译器保持一致)是发出错误消息并立即停止编译。编译器退出并报告失败。
编译需要的内存量取决于多个参数,包括:
每个过程的大小
优化级别
为虚拟内存设置的限制
磁盘交换文件的大小
在 SPARC 平台上,如果优化器用完了所有内存,那么它将通过在较低优化级别上重试当前过程来尝试恢复。然后优化器将以在命令行上通过 -xOlevel 选项指定的原始级别恢复后续例程。
如果编译包括大量例程的单独源文件,编译器可能会用完所有内存或交换空间。如果编译器用完了内存,可以尝试降低优化级别。或者,可以将多例程的源文件分割为单例程的文件。
swap -s 命令用于显示可用的交换空间。有关更多信息,请参见 swap(1M) 手册页。
以下示例演示了 swap 命令的用法:
example% swap -s total: 40236k bytes allocated + 7280k reserved = 47516k used, 1058708k available |
使用 mkfile(1M) 和 swap(1M) 可增加工作站上交换空间的大小。(您必须成为超级用户才能执行该操作)。mkfile 用于命令创建特定大小的文件,而 swap -a 用于将文件增加到系统交换空间:
example# mkfile -v 90m /home/swapfile /home/swapfile 94317840 bytes example# /usr/sbin/swap -a /home/swapfile |
在 -xO3 或更高级别编译非常大型的例程(一个过程中有数几千行代码)需要大量内存。在这种情况下,系统性能可能降低。您可以通过限制单个进程的可用虚拟内存量来控制这种情况。
要在 sh shell 中限制虚拟内存,请使用 ulimit 命令。有关更多信息,请参见 sh(1) 手册页。
以下示例显示了如何将虚拟内存限制为 16M。
example$ ulimit -d 16000 |
在 csh shell 中,可使用 limit 命令限制虚拟内存。有关更多信息,请参见 csh(1) 手册页。
下一个示例也显示了如何将虚拟内存限制为 16M。
example% limit datasize 16M |
这些示例都使优化器在数据空间达到 16M 时尝试恢复。
虚拟空间的限制不能大于系统总的可用交换空间。在实际使用时,虚拟空间的限制要足够的小,以允许在大型编译过程中正常使用系统。
请确保编译不会消耗一半以上的交换空间。
对于 32M 的交换空间,请使用以下命令:
在 sh shell 中:
example$ ulimit -d 16000 |
在 csh shell 中:
example% limit datasize 16M |
最佳设置取决于要求的优化程度、实际内存量和可用的虚拟内存量。
example% /usr/sbin/dmesg | grep mem mem = 655360K (0x28000000) avail mem = 602476544 |
可以通过定义特殊的 shell 别名、使用 CCFLAGS 环境变量或使用 make 来简化复杂的编译器命令。
以下示例为带有常用选项的命令定义了别名。
example% alias CCfx "CC -fast -xnolibmil" |
以下示例使用了别名 CCfx。
example% CCfx any.C |
现在命令 CCfx 等效于:
example% CC -fast -xnolibmil any.C |
可以通过设置 CCFLAGS 变量来指定选项。
可以在命令行中显式使用 CCFLAGS 变量。以下示例说明了如何设置 CCFLAGS (C Shell):
example% setenv CCFLAGS ’-xO2 -xsb’ |
以下示例显式使用了 CCFLAGS。
example% CC $CCFLAGS any.cc |
使用 make 时,如果像上述示例那样设置 CCFLAGS 变量,且 makefile 的编译规则是隐式的,那么在编译时调用 make 等效于:
CC -xO2 -xsb files...
make 实用程序是功能非常强大的程序开发工具,可以方便地与所有 Sun 编译器一起使用。有关更多信息,请参见 make(1S) 手册页。
使用 makefile 的隐式编译规则时(即没有 C++ 编译行),make 程序会自动使用 CCFLAGS。
您可以将不同的文件后缀增加到 makefile 以使它们收入 C++ 中。以下示例为 C++ 文件添加有效后缀 .cpp。可将 SUFFIXES 宏添加到 makefile:
SUFFIXES: .cpp .cpp~
(此行可以放置在 makefile 的任何位置。)
将以下各行增加到 makefile。缩进的行必须以制表符开头。
.cpp: $(LINK.cc) -o $@ $< $(LDLIBS) .cpp~: $(GET) $(GFLAGS) -p $< > $*.cpp $(LINK.cc) -o $@ $*.cpp $(LDLIBS) .cpp.o: $(COMPILE.cc) $(OUTPUT_OPTION) $< .cpp~.o: $(GET) $(GFLAGS) -p $< > $*.cpp $(COMPILE.cc) $(OUTPUT_OPTION) $< .cpp.a: $(COMPILE.cc) -o $% $< $(COMPILE.cc) -xar $@ $% $(RM) $% .cpp~.a: $(GET) $(GFLAGS) -p $< > $*.cpp $(COMPILE.cc) -o $% $< $(COMPILE.cc) -xar $@ $% $(RM) $% |
标准库文件 名称没有 .h 后缀,而是命名为 istream、fstream 等。此外,模板源文件命名为 istream.cc、fstream.cc 等。
本章解释了如何使用命令行 C++ 编译器选项,并按功能汇总它们的使用。16.8 使用 dlopen 从 C 程序访问 C++ 库对这些选项进行了详细介绍。
下表显示了本书中使用的典型选项语法格式的示例。
表 3–1 选项语法格式示例
语法格式 |
示例 |
---|---|
-选项 |
–E |
–选项值 |
–Ipathname |
–选项=值 |
–xunroll=4 |
–选项 值 |
–o filename |
圆括号、大括号、方括号、"|" 或 "-" 字符以及省略号是选项说明中使用的元字符,而不是选项自身的一部分。关于使用语法的详细解释,请参见本手册前面的“开始之前”中的印刷约定。
C++ 编译器选项的某些通用指南:
– llib 选项用于与库 liblib.a(或 liblib.so) 链接。较稳妥的方式是总是将 – llib 放在源文件和目标文件后面,这样可以确保库搜索顺序。
通常,编译器选项的处理顺序是从左到右(有个特殊情况,即 – U 选项在所有 – D 选项之后处理),从而可以有选择地覆盖宏选项(包括其他选项的选项)。此规则不适用于链接程序选项。
-features、–I -l、–L、-library、–pti、–R、-staticlib、-U、-verbose 和 -xprefetch 选项会累积,但不覆盖。
-D 选项会累积,但相同名称的多个 -D 选项会互相覆盖。
在本节中,编译器选项按功能分组以便提供快速参考。有关每个选项的详细介绍,请参见16.8 使用 dlopen 从 C 程序访问 C++ 库。
这些选项适用于除了特别注明之外的所有平台;基于 SPARC 的系统上的 Solaris OS 特有的功能标识为 SPARC,基于 x86 的系统上的 Solaris OS 特有的功能标识为 x86。
选项 |
操作 |
---|---|
–compat |
设置编译器的主发行版本兼容模式。 |
+e{0|1} |
控制虚拟表的生成。 |
–g |
用于与调试一起使用的编译。 |
–KPIC |
生成位置独立的代码。 |
–Kpic |
生成位置独立的代码。 |
–mt |
编译和链接多线程代码。 |
–xcode=a |
(SPARC) 指定代码地址空间。 |
–xMerge |
(SPARC) 将数据段和文本段合并。 |
–xmodel |
针对 Solaris x86 平台修改 64 位对象形式 |
+w |
标识可能产生不可预料结果的代码。 |
+w2 |
发出由 +w 发出的所有警告以及关于技术违规的警告,这些技术违规可能是无害的,但可能会降低程序的最大可移植性。 |
-xregs |
如果编译器可以使用更多的寄存器用于临时存储(临时寄存器),那么编译器将能生成速度更快的代码。该选项使得附加临时寄存器可用,而这些附加寄存器通常是不适用的。 |
-z arg |
链接程序选项。 |
选项 |
操作 |
---|---|
–instlib |
禁止生成已出现在指定库中的模板实例。 |
-m32|-m64 |
指定编译的二进制对象的内存模型。 |
-xinstrument |
编译程序并为其提供程序设备以便 Thread Analyzer 对其进行分析。 |
–xjobs |
设置编译器可以为完成工作而创建的进程数量。 |
–xpch |
可以减少应用程序的编译时间,该应用程序的源文件共享一组共同的 include 文件。 |
–xpchstop |
指定在使用 -xpch 选项创建预编译头文件时要考虑的最后一个 include 文件。 |
–xprofile_ircache |
(SPARC) 重新使用在执行 -xprofile=collect 期间保存的编译数据。 |
–xprofile_pathmap |
(SPARC) 支持单个配置文件目录中有多个程序或共享库。 |
选项 |
操作 |
---|---|
+d |
不扩展 C++ 内联函数。 |
–dryrun |
显示但不编译由驱动程序传递到编译器的选项。 |
–E |
仅对 C++ 源文件运行预处理程序,并将结果发送到 stdout。不编译。 |
–g |
用于与调试一起使用的编译。 |
–g0 |
编译以便进行调试,但不禁用内联。 |
–H |
打印包含文件的路径名称。 |
–keeptmp |
保留编译时创建的临时文件。 |
–migration |
解释可以从早期编译器获得有关移植信息的位置。 |
–P |
仅预处理源文件,输出到 .i 文件。 |
–Qoption |
直接将选项传递到编译阶段。 |
–readme |
显示联机 README 文件的内容。 |
–s |
从可执行文件中去掉符号表,这样可以保护调试代码的能力。 |
–temp=dir |
为临时文件定义目录。 |
–verbose=vlst |
控制编译器详细内容。 |
-xcheck |
对栈溢出增加一个运行时检查。 |
-xdumpmacros |
打印诸如定义、定义及未定义的位置和已使用的位置的宏信息。 |
–xe |
仅检查语法和语义错误。 |
–xhelp=flags |
显示编译器选项汇总列表。 |
–xport64 |
对 32 位体系结构到 64 位体系结构的移植过程中的常见问题发出警告。 |
–xs |
允许在没有目标 (.o) 文件的情况下使用 dbx 进行调试。 |
–xsb |
为源码浏览器生成表信息。 |
–xsbfast |
仅生成源代码浏览器信息,而不进行编译。 |
选项 |
操作 |
---|---|
-fma |
(SPARC) 启用自动生成浮点乘加指令。 |
–fns[={no|yes}] |
(SPARC) 禁用或启用 SPARC 非标准浮点模式。 |
–fprecision=p |
x86:设置浮点精度模式。 |
–fround=r |
设置启动时生效的 IEEE 舍入模式。 |
–fsimple=n |
设置浮点优化首选项。 |
–fstore |
x86:强制浮点表达式的精度。 |
–ftrap=tlst |
设置启动时生效的 IEEE 陷阱操作模式。 |
–nofstore |
x86:禁用表达式的强制精度。 |
–xlibmieee |
使 libm 在异常情况下对于数学例程返回 IEEE 754 值。 |
选项 |
操作 |
---|---|
–compat |
设置编译器的主发行版本兼容模式。 |
–features=alst |
启用或禁用各种 C++ 语言特性。 |
-xchar |
在 char 类型定义为无符号的系统上,简化代码的移植。 |
–xldscope |
控制变量和函数定义的缺省链接程序范围,以创建更快更安全的共享库。 |
–xthreadvar |
(SPARC) 更改缺省的线程局部存储访问模式。 |
-xtrigraphs |
启用三字母序列的识别。 |
–xustr |
启用识别由 16 位字符构成的字符串文字。 |
选项 |
操作 |
---|---|
–Bbinding |
请求符号、动态或静态库链接。 |
–d{y|n} |
允许或不允许整个可执行文件的动态库。 |
–G |
生成动态共享库来取代可执行文件。 |
–hname |
为生成的动态共享库指定名称。 |
–i |
通知 ld(1) 忽略任何 LD_LIBRARY_PATH 设置。 |
–Ldir |
将 dir 添加到要在其中搜索库的目录列表。 |
–llib |
将 liblib.a 或 liblib.so 添加到链接程序的库搜索列表。 |
–library=llst |
强制将特定库和相关文件包含到编译和链接中。 |
–mt |
编译和链接多线程代码。 |
–norunpath |
不将库的路径生成到可执行文件中。 |
–Rplst |
将动态库搜索路径生成到可执行文件中。 |
–staticlib=llst |
说明哪些 C++ 库是静态链接的。 |
–xar |
创建归档库。 |
-xbuiltin[=opt] |
启用或禁用标准库调用的更多优化。 |
-xia |
(SPARC) 链接合适的区间运算库并设置适当的浮点环境。 |
-xlang=l[,l] |
包含适当的运行库,并确保指定语言的正确运行时环境。 |
–xlibmieee |
使 libm 在异常情况下对于数学例程返回 IEEE 754 值。 |
–xlibmil |
内联选定的 libm 库例程以进行优化。 |
–xlibmopt |
使用优化数学例程的库。 |
-xlic_lib=sunperf |
(SPARC) 在 Sun Performance LibraryTM 中进行链接。请注意,对于 C++,-library=sunperf 是在该库中进行链接的首选方法。 |
-xnativeconnect |
将接口信息包含在目标文件和后续共享库中,以便共享库可以与采用 JavaTM 编程语言编写的代码进行接口连接。 |
–xnolib |
禁止链接缺省系统库。 |
–xnolibmil |
在命令行上取消 – xlibmil。 |
–xnolibmopt |
不使用数学例程库。 |
选项 |
操作 |
---|---|
–xlic_lib=sunperf |
(SPARC) 在 Sun Performance Library 中进行链接。请注意,对于 C++,-library=sunperf 是在该库中进行链接的首选方法。 |
–xlicinfo |
显示许可证服务器信息。 |
以下选项要么当前已废弃所以编译器不再接受它们,要么将从以后的发行版中删除。
选项 |
操作 |
---|---|
-library=%all |
废弃的选项,在以后的发行版本中将被删除。 |
–noqueue |
禁用许可证队列。 |
-ptr |
编译器忽略。以后的编译器发行版本可以使用其他行为来重用该选项。 |
-vdelx |
废弃的选项,在以后的发行版本中将被删除。 |
-xcg89 |
使用 -xtarget=ss2。 |
-xnativeconnect |
已废弃,没有替代选项。 |
-xprefetch=yes |
改用 -xprefetch=auto,explicit。 |
-xprefetch=no |
改用 -xprefetch=no%auto,no%explicit。 |
选项 |
操作 |
---|---|
–c |
仅编译;生成目标 (.o) 文件,但抑制链接。 |
–dryrun |
显示但不编译由驱动程序传递到编译器的选项。 |
–E |
仅对 C++ 源文件运行预处理程序,并将结果发送到 stdout。不编译。 |
-erroff |
禁止编译器警告消息。 |
-errtags |
显示每条警告消息的消息标记。 |
-errwarn |
如果发出指示的警告消息,cc 将以失败状态退出。 |
-filt |
禁止编译器应用到链接程序错误消息的过滤。 |
–G |
生成动态共享库来取代可执行文件。 |
–H |
打印包含文件的路径名称。 |
–migration |
解释可以从早期编译器获得有关移植信息的位置。 |
–o filename |
将输出文件或可执行文件的名称设置为 filename。 |
–P |
仅预处理源文件,输出到 .i 文件。 |
–Qproduce sourcetype |
使 CC 驱动程序生成类型为 sourcetype 的输出。 |
–s |
从可执行文件去掉符号表。 |
–verbose=vlst |
控制编译器详细内容。 |
+w |
必要时打印附加警告。 |
–w |
禁止警告消息。 |
-xdumpmacros |
打印诸如定义、定义及未定义的位置和已使用的位置的宏信息。 |
-xe |
对源文件仅执行语法和语义检查,但不生成任何对象或可执行代码。 |
–xhelp=flags |
显示编译器选项汇总列表。 |
–xhelp=readme |
显示联机 README 文件的内容。 |
–xM |
输出 makefile 依赖性信息。 |
–xM1 |
生成依赖性信息,但排除 /usr/include。 |
–xsb |
为源码浏览器生成表信息。 |
–xsbfast |
仅生成源代码浏览器信息,而不进行编译。 |
–xtime |
报告每个编译阶段的执行时间。 |
–xwe |
通过返回非零的退出状态,将所有警告转换成错误。 |
-z arg |
选项 |
操作 |
---|---|
–fast |
选择编译选项的组合以优化某些程序的执行速度。 |
-fma |
(SPARC) 启用自动生成浮点乘加指令。 |
-g |
指示编译器和链接程序准备程序以进行性能分析(以及调试)。 |
–s |
从可执行文件去掉符号表。 |
-m32|-m64 |
指定编译的二进制对象的内存模型。 |
-xalias_level |
启用编译器执行基于类型的别名分析和优化。 |
–xarch=isa |
指定目标体系结构指令集。 |
-xbinopt |
准备二进制文件以便以后进行优化、转换和分析。 |
-xbuiltin[=opt] |
启用或禁用标准库调用的更多优化。 |
–xcache=c |
(SPARC) 定义优化器的目标高速缓存属性。 |
–xcg89 |
为通用 SPARC 体系结构编译。 |
–xcg92 |
为 SPARC V8 体系结构编译。 |
–xchip=c |
指定目标处理器芯片。 |
–xF |
启用函数和变量的链接程序重新排序。 |
-xinline=flst |
指定用户编写的哪些例程可以被优化器内联 |
-xipo |
执行过程间的优化。 |
–xlibmil |
内联选定的 libm 库例程以进行优化。 |
–xlibmopt |
使用优化数学例程的库。 |
–xlinkopt |
(SPARC) 在对目标文件进行优化的基础上对生成的可执行文件或动态库执行链接时优化。 |
–xmemalign=ab |
(SPARC) 指定假定的最大内存对齐以及未对齐的数据访问的行为。 |
–xnolibmil |
在命令行上取消 – xlibmil。 |
–xnolibmopt |
不使用数学例程库。 |
–xOlevel |
将优化级别指定为 level。 |
–xpagesize |
设置栈和堆的首选页面大小。 |
-xpagesize_heap |
设置堆的首选页面大小。 |
-xpagesize_stack |
设置栈的首选页面大小。 |
-xprefetch[=lst] |
(SPARC) 在支持预取的体系结构上启用预取指令。 |
-xprefetch_level |
控制 -xprefetch=auto 设置的自动插入预取指令的主动性。 |
–xprofile |
(SPARC) 收集运行时文件配置数据或使用运行时文件配置数据进行优化。 |
–xregs=rlst |
(SPARC) 控制临时寄存器的使用。 |
–xsafe=mem |
(SPARC) 允许无基于内存的陷阱。 |
–xspace |
(SPARC) 不允许会增大代码大小的优化。 |
–xtarget=t |
指定目标指令集和优化系统。 |
–xthreadvar |
(SPARC) 更改缺省的线程局部存储访问模式。 |
–xunroll=n |
启用在可能的场合下解开循环。 |
–xvis |
(SPARC) 使编译器可以识别 VISTM 指令集中定义的汇编语言模板。 |
选项 |
操作 |
---|---|
–Dname[=def] |
为预处理程序定义符号 name。 |
–E |
仅对 C++ 源文件运行预处理程序,并将结果发送到 stdout。不编译。 |
-H |
打印包含文件的路径名称。 |
–P |
仅预处理源文件,输出到 .i 文件。 |
–Uname |
删除预处理程序符号 name 的初始定义。 |
–xM |
输出 makefile 依赖性信息。 |
–xM1 |
生成依赖性信息,但排除 /usr/include。 |
选项 |
操作 |
---|---|
–p |
准备目标代码来收集数据以使用 prof 进行文件配置。 |
–xa |
为文件配置生成代码。 |
–xpg |
编译以便使用 gprof 配置程序进行文件配置。 |
–xprofile |
(SPARC) 收集运行时文件配置数据或使用运行时文件配置数据进行优化。 |
选项 |
操作 |
---|---|
–migration |
解释可以从早期编译器获得有关移植信息的位置。 |
–xhelp=flags |
显示编译器选项汇总列表。 |
–xhelp=readme |
显示联机 README 文件的内容。 |
选项 |
操作 |
---|---|
-H |
打印包含文件的路径名称。 |
–Ipathname |
将 pathname 添加到 include 文件搜索路径。 |
-I- |
更改包含文件搜索规则 |
–xM |
输出 makefile 依赖性信息。 |
–xM1 |
生成依赖性信息,但排除 /usr/include。 |
选项 |
操作 |
---|---|
–instances=a |
控制模板实例的放置和链接。 |
–ptipath |
为模板源文件指定附加搜索目录。 |
–template=wlst |
启用或禁用各种模板选项。 |
选项 |
操作 |
---|---|
–mt |
编译和链接多线程代码。 |
–xsafe=mem |
(SPARC) Allows no memory-based traps. |
–xthreadvar |
(SPARC) 更改缺省的线程局部存储访问模式。 |