SunStudio12:C++用户指南SunMicrosystems,Inc.
4150NetworkCircleSantaClara,CA95054U.
S.
A.
文件号码820–1214–10版权所有2007SunMicrosystems,Inc.
4150NetworkCircle,SantaClara,CA95054U.
S.
A.
保留所有权利.
对于本文档中介绍的产品,SunMicrosystems,Inc.
对其所涉及的技术拥有相关的知识产权.
需特别指出的是(但不局限于此),这些知识产权可能包含一项或多项美国专利,以及在美国和其他国家/地区申请的待批专利.
美国政府权利-商业软件.
政府用户应遵循SunMicrosystems,Inc.
的标准许可协议,以及FAR(FederalAcquisitionRegulations,即"联邦政府采购法规")的适用条款及其补充条款.
本发行版可能包含由第三方开发的内容.
本产品的某些部分可能是从BerkeleyBSD系统衍生出来的,并获得了加利福尼亚大学的许可.
UNIX是X/OpenCompany,Ltd.
在美国和其他国家/地区独家许可的注册商标.
Sun、SunMicrosystems、Sun徽标、Solaris徽标、Java咖啡杯徽标、docs.
sun.
com、Java和Solaris是SunMicrosystems,Inc.
在美国和其他国家/地区的商标或注册商标.
所有SPARC商标的使用均已获得许可,它们是SPARCInternational,Inc.
在美国和其他国家/地区的商标或注册商标.
标有SPARC商标的产品均基于由SunMicrosystems,Inc.
开发的体系结构.
OPENLOOK和SunTM图形用户界面是SunMicrosystems,Inc.
为其用户和许可证持有者开发的.
Sun感谢Xerox在研究和开发可视或图形用户界面的概念方面为计算机行业所做的开拓性贡献.
Sun已从Xerox获得了对Xerox图形用户界面的非独占性许可证,该许可证还适用于实现OPENLOOKGUI和在其他方面遵守Sun书面许可协议的Sun许可证持有者.
本出版物所介绍的产品以及所包含的信息受美国出口控制法制约,并应遵守其他国家/地区的进出口法律.
严禁将本产品直接或间接地用于核设施、导弹、生化武器或海上核设施,也不能直接或间接地出口给核设施、导弹、生化武器或海上核设施的最终用户.
严禁出口或转口到美国禁运的国家/地区以及美国禁止出口清单中所包含的实体,包括但不限于被禁止的个人以及特别指定的国家/地区的公民.
本文档按"原样"提供,对于所有明示或默示的条件、陈述和担保,包括对适销性、适用性或非侵权性的默示保证,均不承担任何责任,除非此免责声明的适用范围在法律上无效.
070722@18135目录前言19第1部分C++编译器271C++编译器291.
1SunStudio12C++5.
9编译器的新特性和新功能291.
1.
1为64位平台进行编译301.
1.
2x86特别说明301.
1.
3二进制兼容性验证301.
2标准一致性311.
3C++自述文件311.
4手册页321.
5C++实用程序321.
6本地语言支持322使用C++编译器352.
1入门352.
2调用编译器362.
2.
1命令语法362.
2.
2文件名称约定372.
2.
3使用多个源文件382.
3使用不同编译器版本进行编译382.
4编译和链接382.
4.
1编译和链接序列382.
4.
2分别编译和链接392.
4.
3一致编译和链接392.
4.
4针对SPARCV9编译4032.
4.
5诊断编译器402.
4.
6了解编译器的组织412.
5预处理指令和名称422.
5.
1Pragma422.
5.
2具有可变数目的参数的宏422.
5.
3预定义的名称432.
5.
4#error432.
6内存要求432.
6.
1交换空间大小432.
6.
2增加交换空间432.
6.
3虚拟内存的控制442.
6.
4内存要求442.
7简化命令452.
7.
1在CShell中使用别名452.
7.
2使用CCFLAGS指定编译选项452.
7.
3使用make453使用C++编译器选项473.
1语法473.
2通用指南473.
3按功能汇总的选项483.
3.
1代码生成选项483.
3.
2编译时性能选项493.
3.
3调试选项493.
3.
4浮点选项503.
3.
5语言选项513.
3.
6库选项513.
3.
7许可证选项533.
3.
8废弃的选项533.
3.
9输出选项533.
3.
10运行时性能选项553.
3.
11预处理程序选项563.
3.
12文件配置选项573.
3.
13参考选项573.
3.
14源文件选项57目录SunStudio12:C++用户指南43.
3.
15模板选项583.
3.
16线程选项58第2部分编写C++程序594语言扩展614.
1链接程序作用域614.
2线程局部存储624.
3用限制较少的虚函数覆盖634.
4对enum类型和变量进行前向声明634.
5使用不完整enum类型644.
6将enum名称作为作用域限定符644.
7使用匿名struct声明644.
8传递匿名类实例的地址654.
9将静态名称空间作用域函数声明为类友元664.
10将预定义__func__符号用于函数名665程序组织675.
1头文件675.
1.
1可适应语言的头文件675.
1.
2幂等头文件685.
2模板定义695.
2.
1包括的模板定义695.
2.
2独立的模板定义696创建和使用模板716.
1函数模板716.
1.
1函数模板声明716.
1.
2函数模板定义716.
1.
3函数模板用法726.
2类模板726.
2.
1类模板声明726.
2.
2类模板定义726.
2.
3类模板成员定义73目录56.
2.
4类模板的用法746.
3模板实例化746.
3.
1隐式模板实例化756.
3.
2显式模板实例化756.
4模板组合766.
5缺省模板参数766.
6模板专门化766.
6.
1模板专门化声明766.
6.
2模板专门化定义776.
6.
3模板专门化使用和实例化776.
6.
4部分专门化776.
7模板问题部分786.
7.
1非本地名称解析和实例化786.
7.
2作为模板参数的本地类型796.
7.
3模板函数的友元声明796.
7.
4在模板定义内使用限定名称816.
7.
5嵌套模板名称826.
7.
6引用静态变量和静态函数826.
7.
7在同一目录中使用模板生成多个程序827编译模板857.
1冗余编译857.
2系统信息库管理857.
2.
1生成的实例857.
2.
2整个类实例化857.
2.
3编译时实例化867.
2.
4模板实例的放置和链接867.
3外部实例877.
3.
1可能的缓存冲突877.
3.
2静态实例887.
3.
3全局实例887.
3.
4显式实例887.
3.
5半显式实例897.
4模板系统信息库897.
4.
1系统信息库结构89目录SunStudio12:C++用户指南67.
4.
2写入模板系统信息库897.
4.
3从多模板系统信息库读取907.
4.
4共享模板系统信息库907.
4.
5通过-instances=extern实现模板实例自动一致907.
5模板定义搜索907.
5.
1源文件位置约定917.
5.
2定义搜索路径917.
5.
3诊断有问题的搜索918异常处理938.
1同步和异步异常938.
2指定运行时错误938.
3禁用异常948.
4使用运行时函数和预定义的异常948.
5将异常与信号和Setjmp/Longjmp混合使用958.
6生成具有异常的共享库959强制类型转换操作979.
1const_cast979.
2reinterpret_cast989.
3static_cast999.
4动态强制类型转换999.
4.
1将分层结构向上强制类型转换999.
4.
2强制类型转换到void*1009.
4.
3将分层结构向下或交叉强制类型转换10010改善程序性能10310.
1避免临时对象10310.
2使用内联函数10410.
3使用缺省运算符10410.
4使用值类10510.
4.
1选择直接传递类10510.
4.
2在不同的处理器上直接传递类10610.
5缓存成员变量106目录711生成多线程程序10911.
1生成多线程程序10911.
1.
1表明多线程编译10911.
1.
2与线程和信号一起使用C++支持库11011.
2在多线程程序中使用异常11011.
2.
1线程取消11011.
3在线程之间共享C++标准库对象11111.
4在多线程环境中使用传统iostream11211.
4.
1MT安全的iostream库的组织11311.
4.
2iostream库接口更改11811.
4.
3全局和静态数据12111.
4.
4序列执行12111.
4.
5对象锁定12111.
4.
6多线程安全类12311.
4.
7对象析构12411.
4.
8示例应用程序124第3部分库12712使用库12912.
1C库12912.
2随C++编译器提供的库12912.
2.
1C++库描述13012.
2.
2访问C++库的手册页13112.
2.
3缺省C++库13212.
3相关的库选项13212.
4使用类库13412.
4.
1iostream库13412.
4.
2complex库13512.
4.
3链接C++库13612.
5静态链接标准库13712.
6使用共享库13712.
7替换C++标准库13812.
7.
1可以替换的内容13912.
7.
2不可替换的内容139目录SunStudio12:C++用户指南812.
7.
3安装替换库13912.
7.
4使用替换库13912.
7.
5标准头文件实现14013使用C++标准库14313.
1C++标准库头文件14413.
2C++标准库手册页14513.
3STLport15613.
3.
1重新分发和支持的STLport库15714使用传统iostream库15914.
1预定义的iostream15914.
2iostream交互的基本结构16014.
3使用传统iostream库16014.
3.
1使用iostream进行输出16114.
3.
2使用iostream进行输入16414.
3.
3定义自己的提取运算符16414.
3.
4使用char*提取器16414.
3.
5读取任何单一字符16514.
3.
6二进制输入16514.
3.
7查看输入16514.
3.
8提取空白16614.
3.
9处理输入错误16614.
3.
10结合使用iostream与stdio16614.
4创建iostream16714.
4.
1使用类fstream处理文件16714.
5iostream赋值17014.
6格式控制17014.
7操纵符17014.
7.
1使用无格式操纵符17114.
7.
2参数化操纵符17214.
8用于数组的strstream:iostream17414.
9用于stdio文件的stdiobuf:iostream17414.
10streambuf17414.
10.
1streambuf工作方式174目录914.
10.
2使用streambuf17414.
11iostream手册页17514.
12iostream术语17615使用复数运算库17915.
1复数库17915.
1.
1使用复数库17915.
2complex类型18015.
2.
1complex类的构造函数18015.
2.
2算术运算符18115.
3数学函数18115.
4错误处理18315.
5输入和输出18415.
6混合模式运算18415.
7效率18515.
8复数手册页18616生成库18716.
1认识库18716.
2生成静态(归档)库18816.
3生成动态(共享)库18816.
4生成包含异常的共享库18916.
5生成专用的库18916.
6生成公用的库18916.
7生成具有CAPI的库19016.
8使用dlopen从C程序访问C++库190第4部分附录193AC++编译器选项195A.
1选项信息的结构195A.
2选项参考196A.
2.
1–386196A.
2.
2–486196目录SunStudio12:C++用户指南10A.
2.
3–a196A.
2.
4–Bbinding196A.
2.
5–c198A.
2.
6–cg{89|92}198A.
2.
7–compat[={4|5}199A.
2.
8+d200A.
2.
9-Dname[=def]201A.
2.
10–d{y|n}203A.
2.
11–dalign203A.
2.
12–dryrun204A.
2.
13–E204A.
2.
14+e{0|1}205A.
2.
15-erroff[=t]206A.
2.
16-errtags[=a]206A.
2.
17-errwarn[=t]207A.
2.
18–fast208A.
2.
19–features=a[,a.
210A.
2.
20-filt[=filter[,filter.
213A.
2.
21–flags215A.
2.
22-fma[={none|fused}215A.
2.
23–fnonstd216A.
2.
24–fns[={yes|no}216A.
2.
25–fprecision=p217A.
2.
26–fround=r218A.
2.
27–fsimple[=n]219A.
2.
28–fstore221A.
2.
29–ftrap=t[,t.
221A.
2.
30–G222A.
2.
31–g223A.
2.
32–g0224A.
2.
33–H224A.
2.
34–h[]name225A.
2.
35–help225A.
2.
36-Ipathname225A.
2.
37-I-226A.
2.
38–i228目录11A.
2.
39-inline228A.
2.
40–instances=a228A.
2.
41–instlib=filename229A.
2.
42–KPIC230A.
2.
43–Kpic230A.
2.
44–keeptmp230A.
2.
45–Lpath231A.
2.
46–llib231A.
2.
47–libmieee232A.
2.
48–libmil232A.
2.
49-library=l[,l.
232A.
2.
50-m32|-m64235A.
2.
51-mc236A.
2.
52–migration236A.
2.
53–misalign236A.
2.
54-mr[,string]237A.
2.
55–mt237A.
2.
56–native238A.
2.
57–noex238A.
2.
58–nofstore238A.
2.
59–nolib238A.
2.
60–nolibmil239A.
2.
61–noqueue239A.
2.
62–norunpath239A.
2.
63–O239A.
2.
64–Olevel239A.
2.
65–ofilename239A.
2.
66+p240A.
2.
67–P240A.
2.
68–p241A.
2.
69–pentium241A.
2.
70–pg241A.
2.
71-PIC241A.
2.
72–pic241A.
2.
73–pta241A.
2.
74–ptipath241目录SunStudio12:C++用户指南12A.
2.
75–pto242A.
2.
76–ptr242A.
2.
77–ptv242A.
2.
78–Qoptionphaseoption[,option…242A.
2.
79–qoptionphaseoption243A.
2.
80–qp243A.
2.
81–Qproducesourcetype243A.
2.
82–qproducesourcetype244A.
2.
83–Rpathname[:pathname…244A.
2.
84–readme245A.
2.
85–S245A.
2.
86–s245A.
2.
87–sb245A.
2.
88–sbfast245A.
2.
89-staticlib=l[,l…245A.
2.
90-sync_stdio=[yes|no]247A.
2.
91–temp=path248A.
2.
92–template=opt[,opt…248A.
2.
93–time250A.
2.
94–Uname250A.
2.
95–unroll=n250A.
2.
96–V250A.
2.
97–v250A.
2.
98–vdelx251A.
2.
99–verbose=v[,v…251A.
2.
100+w252A.
2.
101+w2252A.
2.
102–w253A.
2.
103–Xm253A.
2.
104–xa253A.
2.
105-xalias_level[=n]254A.
2.
106–xar256A.
2.
107–xarch=isa256A.
2.
108-xautopar262A.
2.
109-xbinopt={prepare|off}262A.
2.
110-xbuiltin[={%all|%none}263目录13A.
2.
111–xcache=c264A.
2.
112-xcg[89|92]265A.
2.
113-xchar[=o]265A.
2.
114-xcheck[=i]266A.
2.
115-xchip=c267A.
2.
116–xcode=a269A.
2.
117-xcrossfile[=n]271A.
2.
118-xdebugformat=[stabs|dwarf]272A.
2.
119-xdepend=[yes|no]273A.
2.
120-xdumpmacros[=value[,value.
273A.
2.
121-xe276A.
2.
122-xF[=v[,v.
276A.
2.
123–xhelp=flags277A.
2.
124–xhelp=readme277A.
2.
125-xhwcprof278A.
2.
126-xia278A.
2.
127-xinline[=func_spec[,func_spec.
279A.
2.
128-xinstrument=[no%]datarace281A.
2.
129-xipo[={0|1|2}281A.
2.
130-xipo_archive=[a]283A.
2.
131-xjobs=n284A.
2.
132-xlang=language[,language]285A.
2.
133-xldscope={v}286A.
2.
134–xlibmieee287A.
2.
135–xlibmil287A.
2.
136–xlibmopt288A.
2.
137–xlic_lib=sunperf288A.
2.
138–xlicinfo288A.
2.
139-xlinkopt[=level]288A.
2.
140–xM290A.
2.
141-xM1290A.
2.
142–xMerge290A.
2.
143-xmaxopt[=v]291A.
2.
144-xmemalign=ab291A.
2.
145-xmodel=[a]292A.
2.
146–xnolib293目录SunStudio12:C++用户指南14A.
2.
147–xnolibmil295A.
2.
148–xnolibmopt295A.
2.
149-xnorunpath295A.
2.
150-xOlevel295A.
2.
151-xopenmp[=i]298A.
2.
152-xpagesize=n299A.
2.
153-xpagesize_heap=n300A.
2.
154-xpagesize_stack=n301A.
2.
155-xpch=v302A.
2.
156-xpchstop=file304A.
2.
157–xpg305A.
2.
158-xport64[=(v305A.
2.
159-xprefetch[=a[,a.
308A.
2.
160-xprefetch_auto_type=a310A.
2.
161-xprefetch_level[=i]310A.
2.
162-xprofile=p311A.
2.
163-xprofile_ircache[=path]313A.
2.
164-xprofile_pathmap314A.
2.
165–xregs=r[,r.
314A.
2.
166-xrestrict[=f]316A.
2.
167–xs318A.
2.
168–xsafe=mem318A.
2.
169–xsb318A.
2.
170–xsbfast318A.
2.
171–xspace318A.
2.
172–xtarget=t318A.
2.
173-xthreadvar[=o]325A.
2.
174–xtime326A.
2.
175-xtrigraphs[={yes|no}327A.
2.
176–xunroll=n328A.
2.
177-xustr={ascii_utf16_ushort|no}328A.
2.
178-xvector[=a]329A.
2.
179-xvis[={yes|no}330A.
2.
180–xwe330A.
2.
181-Yc,path330A.
2.
182-z[]arg331目录15BPragma333B.
1Pragma形式333B.
1.
1将函数作为pragma参数进行重载333B.
2Pragma参考334B.
2.
1#pragmaalign335B.
2.
2#pragmadoes_not_read_global_data336B.
2.
3#pragmadoes_not_return336B.
2.
4#pragmadoes_not_write_global_data337B.
2.
5#pragmadumpmacros337B.
2.
6#pragmaend_dumpmacros338B.
2.
7#pragmafini338B.
2.
8#pragmahdrstop338B.
2.
9#pragmaident339B.
2.
10#pragmainit339B.
2.
11#pragmano_side_effect339B.
2.
12#pragmaopt340B.
2.
13#pragmapack(n)340B.
2.
14#pragmararely_called342B.
2.
15#pragmareturns_new_memory342B.
2.
16#pragmaunknown_control_flow342B.
2.
17#pragmaweak343词汇表345索引349目录SunStudio12:C++用户指南16示例示例6–1本地类型用作模板参数问题的示例79示例6–2友元声明问题的示例80示例11–1检查错误状态115示例11–2调用gcount116示例11–3用户定义的I/O操作116示例11–4禁用多线程安全117示例11–5切换到多线程不安全118示例11–6在多线程不安全的对象中使用同步118示例11–7新增类118示例11–8新增类的分层结构119示例11–9新函数119示例11–10使用锁定操作的示例122示例11–11令I/O操作和错误检查独立化123示例11–12销毁共享对象124示例11–13以MT安全方式使用iostream对象124示例14–1string提取运算符164示例A–1预处理程序示例foo.
cc204示例A–2使用-E选项时foo.
cc的预处理程序输出204示例A–3带两个指针的循环3171718前言本手册指导您如何使用SunTMStudio12的C++编译器,并提供有关命令行编译器选项的详细信息.
本手册适用于精通C++并对SolarisTM操作系统和UNIX命令有一定了解的程序员.
本书的结构本手册包含如下主题:C++编译器.
第1章提供有关此编译器的介绍性信息,如标准的一致性和新增功能.
第2章介绍如何使用此编译器,第3章介绍如何使用此编译器的命令行选项.
编写C++程序.
第4章讨论如何编译其他C++编译器通常接受的非标准代码.
第5章就如何设置和组织头文件和模板定义提供了一些建议.
第6章介绍如何创建和使用模板,第7章介绍用来编译模板的各种选项.
第8章介绍异常处理,第9章提供有关强制类型转换操作的信息.
第10章介绍对C++编译器有很大影响的性能技术.
第11章提供有关生成多线程程序的信息.
库.
第12章介绍如何使用该编译器提供的库.
第13章介绍C++标准库,第14章介绍传统iostream库(适用于兼容模式),第15章介绍复数运算库(适用于兼容模式).
第16章提供有关生成库的信息.
附录.
附录A按字母顺序列出了完整的C++编译器选项集,附录B列出了C++编译器pragma.
19印刷约定表P–1字体约定表字体含义示例AaBbCc123命令、文件和目录的名称;计算机屏幕输出编辑.
login文件.
使用ls-a列出所有文件.
%Youhavemail.
AaBbCc123用户键入的内容,与计算机屏幕输出的显示不同%suPassword:AaBbCc123要使用实名或值替换的命令行占位符文本要删除文件,请键入rmfilename.
AaBbCc123保留未译的新词或术语以及要强调的词这些称为class选项.
新词术语强调新词或术语以及要强调的词您必须成为超级用户才能执行此操作.
《书名》书名阅读《用户指南》的第6章.
表P–2代码约定表代码符号含义表示法代码示例[]方括号中的参数是可选参数.
O[n]O4,O{}大括号中是针对所需选项的一组选择内容.
d{y|n}dy|"|"或"-"符号用于分隔多个参数,只能选择其中一个参数.
B{dynamic|static}Bstatic:冒号与逗号类似,有时用于分隔多个参数.
Rdir[:dir]R/local/libs:/U/a…省略号表示一系列省略.
xinline=f1[,…fn]xinline=alpha,dos前言SunStudio12:C++用户指南20Shell提示符Shell提示符Cshellmachine-name%Cshell超级用户machine-name#Bourneshell、Kornshell和GNUBourne-Againshell$Bourneshell、Kornshell和GNUBourne-Againshell超级用户#受支持的平台此SunStudio发行版支持使用SPARC和x86系列处理器体系结构的系统:UltraSPARC、SPARC64、AMD64、Pentium和XeonEM64T.
可从以下位置获得硬件兼容性列表,在列表中可以查看您正在使用的Solaris操作系统版本所支持的系统:http://www.
sun.
com/bigadmin/hcl.
这些文档中给出了平台类型间所有实现的区别.
在本文档中,与x86相关的术语的含义如下:"x86"泛指64位和32位的x86兼容产品系列.
"x64"表示有关AMD64或EM64T系统的特定64位信息.
"32位x86"表示有关基于x86的系统的特定32位信息.
有关受支持的系统,请参阅硬件兼容性列表.
访问SunStudio文档可以访问以下位置的文档:可以通过随软件一起安装在本地系统或网络上的文档索引(在Solaris平台上为file:/opt/SUNWspro/docs/index.
html;在Linux平台上为file:/opt/sun/sunstudio12/docs/index.
html)获取文档.
如果该软件没有安装在/opt目录(Solaris平台)中或/opt/sun目录(Linux平台)中,请询问系统管理员以获取系统中的等效路径.
可以从docs.
sun.
comsmWeb站点获取大多数手册.
下列书目只能从Solaris平台上已安装的软件中获取:《标准C++库类参考》《标准C++库用户指南》前言21《Tools.
h++类库参考》《Tools.
h++用户指南》Solaris平台和Linux平台的相应发行说明可从docs.
sun.
comWeb站点获取.
IDE所有组件的联机帮助可通过IDE中的"帮助"菜单以及许多窗口和对话框上的"帮助"按钮获取.
可以通过Internet访问docs.
sun.
comWeb站点(http://docs.
sun.
com)阅读、打印和购买SunMicrosystems的各种手册.
如果找不到某手册,请参见随软件一起安装在本地系统或网络上的文档索引.
注–Sun对本文档中提到的第三方Web站点的可用性不承担任何责任.
对于此类站点或资源中的(或通过它们获得的)任何内容、广告、产品或其他资料,Sun并不表示认可,也不承担任何责任.
对于因使用或依靠此类站点或资源中的(或通过它们获得的)任何内容、产品或服务而造成的或连带产生的实际或名义损坏或损失,Sun概不负责,也不承担任何责任.
采用易读格式的文档该文档以易读格式提供,以方便残障用户使用辅助技术进行阅读.
可以按照下表所述找到文档的易读版本.
如果该软件未安装在/opt目录中,请询问系统管理员以获取系统中的等效路径.
文档类型易读版本的格式和位置手册(第三方手册除外)HTML,位于http://docs.
sun.
com第三方手册:《标准C++库类参考》《标准C++库用户指南》《Tools.
h++类库参考》《Tools.
h++用户指南》HTML,位于Solaris平台上已安装软件中,可通过文档索引(file:/opt/SUNWspro/docs/index.
html)获取自述文件HTML,位于SunDeveloperNetwork门户http://developers.
sun.
com/sunstudio/documentation/ss12前言SunStudio12:C++用户指南22手册页HTML,位于已安装软件中,可通过文档索引(在Solaris平台上为file:/opt/SUNWspro/docs/index.
html;在Linux平台上为file:/opt/sun/sunstudio12/docs/index.
html)获取联机帮助HTML,可通过IDE中的"帮助"菜单和"帮助"按钮获取发行说明HTML,位于http://docs.
sun.
com相关SunStudio文档下表列出了可通过file:/opt/SUNWspro/docs/index.
html和http://docs.
sun.
com获取的相关文档.
如果该软件未安装在/opt目录中,请询问系统管理员以获取系统中的等效路径.
文档标题说明《C用户指南》提供了所有编译器选项的参考、支持的ISO/IEC9899:1999(称为C99)功能的说明、实现细节(如pragma和声明说明符)以及有关使用lint代码检查程序的完整信息.
《C++用户指南》介绍了如何使用C++编译器,还提供了有关命令行编译器选项、程序组织、pragma、模板、异常处理、使用强制类型转换运算符以及使用和生成库的详细信息.
《Fortran编程指南》介绍了如何在Solaris环境中编写高效Fortran程序;并介绍了输入/输出、库、性能、调试和并行处理.
《Fortran库参考》详细介绍Fortran库以及内函数.
《OpenMPAPI用户指南》概括介绍了OpenMP多重处理API,并提供了有关实现的具体信息.
《数值计算指南》介绍了与浮点计算的数值精度有关的问题.
前言23访问相关的C++手册页本手册提供了可用于C++库的手册页列表.
下表列出了与C++相关的其他手册页.
标题说明c++filt按顺序复制每个文件名,并在解码类似C++还原名称的符号之后将文件名写入标准输出dem还原指定的一个或多个C++名称fbe从汇编语言源文件创建目标文件fpversion打印系统CPU和FPU的相关信息gprof生成程序的可执行配置文件inline扩展汇编程序的内联过程调用lex生成词法分析程序rpcgen生成C/C++代码以实现RPC协议sigfpe允许对指定SIGFPE代码进行信号处理stdarg处理变量参数列表varargs处理变量参数列表version显示目标文件或二进制文件的版本标识yacc将上下文无关的语法转换成一组表,用于执行LALR(1)分析算法的简单自动化访问Solaris相关文档下表列出了可从docs.
sun.
comWeb站点上获取的相关文档.
文档集合文档标题说明SolarisReferenceManualCollection请参见手册页各章节的标题.
提供Solaris操作系统的有关信息.
SolarisSoftwareDeveloperCollection《链接程序和库指南》介绍了Solaris链接编辑器和运行时链接程序的操作.
前言SunStudio12:C++用户指南24开发者资源访问SunDeveloperNetworkSunStudio门户(http://developers.
sun.
com/prodtech/cc)查看下列经常更新的资源:有关编程技术和最佳做法的文章有关编程小技巧的知识库软件文档以及随软件一起安装的文档的更正信息有关支持级别的信息用户论坛可下载的代码示例新技术预览SunStudio门户是SunDeveloperNetworkWeb站点(http://developers.
sun.
com)上面向开发者的众多其他资源之一.
其他公司出版的书籍以下是部分C++语言书籍的列表.
由BjarneStroustrup编著的第三版《TheC++ProgrammingLanguage》(Addison-Wesley出版,1997).
由NicolaiJosuttis编著的《TheC++StandardLibrary》(Addison-Wesley出版,1999).
由MatthewAustern编著的《GenericProgrammingandtheSTL》(Addison-Wesley出版,1999).
由AngelikaLanger和KlausKreft合著的《StandardC++IOStreamsandLocales》(Addison-Wesley出版,2000).
由BruceEckel编著的《ThinkinginC++,Volume1,SecondEdition》(PrenticeHall出版,2000).
由MargaretA.
Ellis和BjarneStroustrup合著的《TheAnnotatedC++ReferenceManual》(Addison-Wesley出版,1990).
由ErichGamma、RichardHelm、RalphJohnson和JohnVlissides合著的《DesignPatterns:ElementsofReusableObject-OrientedSoftware》(Addison-Wesley出版,1995).
由StanleyB.
Lippman和JoseeLajoie合著的第三版《C++Primer》(Addison-Wesley出版,1998).
由ScottMeyers编著的第二版《EffectiveC++-50WaystoImproveYourProgramsandDesigns》(Addison-Wesley出版,1998).
前言25由ScottMeyers编著的《MoreEffectiveC++-35WaystoImproveYourProgramsandDesigns》(Addison-Wesley出版,1996).
联系Sun技术支持如果您遇到通过本文档无法解决的技术问题,请访问以下URL:http://www.
sun.
com/service/contactingSun欢迎您提出意见Sun致力于提高其文档的质量,并十分乐意收到您的意见和建议.
您可以通过以下URL向Sun提交您的意见:http://www.
sun.
com/hwdocs/feedback请在电子邮件的主题行中注明文档的文件号码.
例如,本文档的文件号码是820-1214-10.
前言SunStudio12:C++用户指南26C++编译器第1部分2728C++编译器本章提供有关以下内容的信息:第29页中的"1.
1SunStudio12C++5.
9编译器的新特性和新功能"第31页中的"1.
2标准一致性"第31页中的"1.
3C++自述文件"第32页中的"1.
4手册页"第32页中的"1.
5C++实用程序"第32页中的"1.
6本地语言支持"1.
1SunStudio12C++5.
9编译器的新特性和新功能本节简要介绍在SunStudio12C++5.
9编译器发行版中引入的C编译器的新特性和新功能.
有关详细的说明,请参见每项的交叉引用.
现在,可以在以下Linux分发(x86和x64)上使用C编译器:带有ServicePack3的SuSELinuxEnterpriseServer9(或更高版本).
RedHatEnterpriseLinux4.
其他基于2.
6内核的Linux分发(尽管它们不受官方支持).
决定内存模型的新-m32|-m64选项.
新的-xarch标志替换了过时的标志.
-xtarget和-xchip的新值为UltraSPARCT2和SPARC64vi处理器提供代码生成.
新标志-fma=fused可在受支持的处理器上启用生成乘加指令.
在x86和SPARC平台上接受显式预取宏.
(-xprefetch=explicit)1第1章291.
1.
1为64位平台进行编译在本发行版中,指定32位或64位二进制的编译的方式已更改.
第256页中的"A.
2.
107–xarch=isa"选项不再采取隐式内存模式(32位ILP32或64位LP64,使用其各自定义),现在仅用于指定目标处理器的指令集.
请使用新的第235页中的"A.
2.
50-m32|-m64"选项来指定目标编译的内存模型.
ILP32模型指定C语言的int、long和指针数据类型的宽度都是32位.
LP64模型指定long和指针数据类型的宽度都是64位.
Solaris和LinuxOS还支持LP64内存模型下的大型文件和大型数组.
如果使用-m64编译,则生成的可执行文件仅能在运行64位内核的SolarisOS或LinuxOS下的64位UltraSPARC(R)或x86处理器上运行.
64位对象的编译、链接和执行只能在支持64位执行的Solaris或LinuxOS上进行.
1.
1.
2x86特别说明针对x86Solaris平台进行编译时,有一些重要问题需要了解.
传统的Sun样式并行化pragma在x86上不可用,而改用OpenMP.
有关将传统并行化指令转换为OpenMP的信息,请参见《SunStudio12:OpenMPAPIUser'sGuide》.
如果编译程序时将-xarch设置为sse、sse2、sse2a或sse3,则这些程序必须仅在提供这些扩展和功能的平台上运行.
从Solaris94/04开始的SolarisOS发行版在Pentium4兼容的平台上启用了SSE/SSE2.
早期版本的SolarisOS未启用SSE/SSE2.
如果运行的SolarisOS中未启用由-xarch选择的指令集,编译器将无法为该指令集生成或链接代码.
如果在不同的步骤中进行编译和链接,请始终使用编译器和相同的-xarch设置进行链接,以确保链接正确的启动例程.
在x86上得到的数值结果可能与在SPARC上得到的结果不同,这是由x8680位浮点寄存器造成的.
为了最大限度减少这些差异,请使用-fstore选项或使用x-arch=sse2进行编译(如果硬件支持SSE2).
Solaris和Linux的数值结果也可能不同,因为内部数学库(如sin(x))并不相同.
1.
1.
3二进制兼容性验证从SunStudio11和Solaris10OS开始,会对使用这些专用的-xarch硬件标志编译和生成的程序二进制文件进行验证,看其是否在适当的平台上运行.
在Solaris10之前的系统中,不执行任何验证,用户负责确保使用这些标志生成的对象部署在合适的硬件上.
1.
1SunStudio12C++5.
9编译器的新特性和新功能SunStudio12:C++用户指南30如果在没有相应功能或指令集扩展的平台上运行使用这些-xarch选项编译的程序,则可能会导致段故障或不正确的结果,并且不显示任何显式警告消息.
此警告还适用于使用利用SSE、SSE2、SSE2a和SSE3指令和扩展的.
il内联汇编语言函数或__asm()汇编程序代码.
1.
2标准一致性C++编译器(CC)支持C++ISO国际标准ISOIS14882:1998,编程语言-C++.
当前发行版本附带的自述文件描述了与标准需求的所有差异.
在SPARCTM平台上,编译器提供了对SPARCV8和SPARCV9(包括UltraSPARCTM实现)优化开发功能的支持.
在Prentice-HallforSPARCInternational发行的第8版(ISBN0-13-825001-4)和第9版(ISBN0-13-099227-5)SPARCArchitectureManual中定义了这些功能.
在本文档中,"标准"是指与上面列出的标准版本相一致.
"非标准"或"扩展"是指这些标准的这些版本之外的功能.
负责标准的一方可能会不时地修订这些标准.
C++编译器兼容的适用标准版本可能被修订或替换,这将会导致以后的SunC++编译器发行版本在功能上与旧的发行版本产生不兼容.
1.
3C++自述文件C++编译器的自述文件列出了关于编译器的重要信息,其中包括:在手册印刷之后发现的信息新特性和更改的特性软件更正问题和解决办法限制和不兼容可发送库未实现的标准要查看C++自述文件的文本格式文件,请在命令提示符后输入以下命令:example%CC-xhelp=readme要访问此自述文件的HTML版本,请在NetscapeCommunicator4.
0或兼容版本的浏览器中打开以下文件:/opt/SUNWspro/docs/index.
html1.
3C++自述文件第1章C++编译器31(如果您的C++编译器软件没有安装在/opt目录中,请通过系统管理员获取您系统中的等效路径.
)浏览器可以显示HTML文档的索引.
要打开自述文件,请在索引中找到其对应条目,然后单击标题.
1.
4手册页联机手册(man)页提供了关于命令、函数、子例程以及收集这些信息的文档.
可以通过运行以下命令来显示手册页:example%mantopic在整个C++文档中,手册页参考以主题名称和手册节编号显示:CC(1)通过manCC进行访问.
例如,可在man命令中使用-s选项来访问ieee_flags(3M)指示的其他部分:example%man-s3Mieee_flags1.
5C++实用程序以下C++实用程序现已并入传统的UNIX工具并且与UNIX操作系统捆绑在了一起:lex-生成用于文本简单词法分析的程序yacc-根据语法生成C函数分析输入流prof-生成程序模块的执行配置文件gprof-按过程来配置程序运行时性能tcov-按语句来配置程序运行时性能有关这些UNIX工具的详细信息,请参见《ProgramPerformanceAnalysisTools》和相关手册页.
1.
6本地语言支持此发行版本的C++支持使用英语以外的其他语言进行应用程序的开发,包括了大多数欧洲语言和日语.
因此,您可以十分便捷地将应用程序从一种语言切换到另一种语言.
此功能被称为国际化.
通常,C++编译器按如下方式实现国际化:C++从国际化的键盘识别ASCII字符(也就是说,它具有键盘独立性和8位清除).
C++允许使用本地语言打印某些消息.
C++允许在注释、字符串和数据中使用本地语言.
1.
4手册页SunStudio12:C++用户指南32C++只支持符合扩展UNIX字符(ExtendedUNIXCharacte,EUC)的字符集,在该字符集中,字符串内每个空字节是一个空字符,而字符串内每个ascii值为"/"的字节是一个"/"字符.
变量名称不能国际化,必须使用英文字符集.
您可以设置语言环境将应用程序从一种本地语言更改为另一种语言.
关于这一点和其他本地语言支持功能的信息,请参见操作系统文档.
1.
6本地语言支持第1章C++编译器3334使用C++编译器本章描述了如何使用C++编译器.
任何编译器的主要用途是将高级语言(如C++)编写的程序转换成目标计算机硬件可执行的数据文件.
您可以使用C++编译器完成以下任务:将源文件转换成可重定位的二进制(.
o)文件(以后链接到可执行文件)、静态(归档)库(.
a)文件(使用–xar)或动态(共享)库(.
so)文件中将目标文件或库文件(或两者)链接或重链接成可执行文件在运行时调试处于启用状态的情况下编译可执行文件(-g)使用运行时语句或过程级文件配置(-pg)编译可执行文件2.
1入门本节简要概述了如何使用C++编译器编译和运行C++程序.
有关命令行选项的完整参考,请参见第190页中的"16.
8使用dlopen从C程序访问C++库".
注–本章中的命令行示例说明了CC的用法.
打印输出可能会稍有不同.
生成和运行C++程序的基本步骤包括:1.
使用编辑器创建C++源文件(后缀为表2–1中所列有效后缀之一)2.
调用编译器来生成可执行文件3.
通过输入可执行文件的名称来启动程序以下程序在屏幕上显示消息:example%catgreetings.
cc#includeintmain(){2第2章35std::couty,"xis%dbutyis%d",x,y);其结果如下:fprintf(stderr,"Flag");fprintf(stderr,"X=%d\n",x);puts("Thefirst,second,andthirditems.
");((x>y)puts("x>y"):printf("xis%dbutyis%d",x,y));2.
5预处理指令和名称SunStudio12:C++用户指南422.
5.
3预定义的名称附录中的表A–2介绍了预定义的宏.
可以在#ifdef这样的预处理程序条件中使用这些值.
+p选项可防止自动定义sun、unix、sparc和i386预定义宏.
2.
5.
4#error发出警告后,#error指令不再继续编译.
指令原来的行为是发出警告并继续编译.
其新行为(和其他编译器保持一致)是发出错误消息并立即停止编译.
编译器退出并报告失败.
2.
6内存要求编译需要的内存量取决于多个参数,包括:每个过程的大小优化级别为虚拟内存设置的限制磁盘交换文件的大小在SPARC平台上,如果优化器用完了所有内存,那么它将通过在较低优化级别上重试当前过程来尝试恢复.
然后优化器将以在命令行上通过-xOlevel选项指定的原始级别恢复后续例程.
如果编译包括大量例程的单独源文件,编译器可能会用完所有内存或交换空间.
如果编译器用完了内存,可以尝试降低优化级别.
或者,可以将多例程的源文件分割为单例程的文件.
2.
6.
1交换空间大小swap-s命令用于显示可用的交换空间.
有关更多信息,请参见swap(1M)手册页.
以下示例演示了swap命令的用法:example%swap-stotal:40236kbytesallocated+7280kreserved=47516kused,1058708kavailable2.
6.
2增加交换空间使用mkfile(1M)和swap(1M)可增加工作站上交换空间的大小.
(您必须成为超级用户才能执行该操作).
mkfile用于命令创建特定大小的文件,而swap-a用于将文件增加到系统交换空间:2.
6内存要求第2章使用C++编译器43example#mkfile-v90m/home/swapfile/home/swapfile94317840bytesexample#/usr/sbin/swap-a/home/swapfile2.
6.
3虚拟内存的控制在-xO3或更高级别编译非常大型的例程(一个过程中有数几千行代码)需要大量内存.
在这种情况下,系统性能可能降低.
您可以通过限制单个进程的可用虚拟内存量来控制这种情况.
要在shshell中限制虚拟内存,请使用ulimit命令.
有关更多信息,请参见sh(1)手册页.
以下示例显示了如何将虚拟内存限制为16M.
example$ulimit-d16000在cshshell中,可使用limit命令限制虚拟内存.
有关更多信息,请参见csh(1)手册页.
下一个示例也显示了如何将虚拟内存限制为16M.
example%limitdatasize16M这些示例都使优化器在数据空间达到16M时尝试恢复.
虚拟空间的限制不能大于系统总的可用交换空间.
在实际使用时,虚拟空间的限制要足够的小,以允许在大型编译过程中正常使用系统.
请确保编译不会消耗一半以上的交换空间.
对于32M的交换空间,请使用以下命令:在shshell中:example$ulimit-d16000在cshshell中:example%limitdatasize16M最佳设置取决于要求的优化程度、实际内存量和可用的虚拟内存量.
2.
6.
4内存要求工作站至少需要64M的内存,推荐使用128M.
要确定实际的真实内存,请使用以下命令:2.
6内存要求SunStudio12:C++用户指南44example%/usr/sbin/dmesg|grepmemmem=655360K(0x28000000)availmem=6024765442.
7简化命令可以通过定义特殊的shell别名、使用CCFLAGS环境变量或使用make来简化复杂的编译器命令.
2.
7.
1在CShell中使用别名以下示例为带有常用选项的命令定义了别名.
example%aliasCCfx"CC-fast-xnolibmil"以下示例使用了别名CCfx.
example%CCfxany.
C现在命令CCfx等效于:example%CC-fast-xnolibmilany.
C2.
7.
2使用CCFLAGS指定编译选项可以通过设置CCFLAGS变量来指定选项.
可以在命令行中显式使用CCFLAGS变量.
以下示例说明了如何设置CCFLAGS(CShell):example%setenvCCFLAGS'-xO2-xsb'以下示例显式使用了CCFLAGS.
example%CC$CCFLAGSany.
cc使用make时,如果像上述示例那样设置CCFLAGS变量,且makefile的编译规则是隐式的,那么在编译时调用make等效于:CC-xO2-xsbfiles.
.
.
2.
7.
3使用makemake实用程序是功能非常强大的程序开发工具,可以方便地与所有Sun编译器一起使用.
有关更多信息,请参见make(1S)手册页.
2.
7简化命令第2章使用C++编译器452.
7.
3.
1在make中使用CCFLAGS使用makefile的隐式编译规则时(即没有C++编译行),make程序会自动使用CCFLAGS.
2.
7.
3.
2为Makefile增加后缀您可以将不同的文件后缀增加到makefile以使它们收入C++中.
以下示例为C++文件添加有效后缀.
cpp.
可将SUFFIXES宏添加到makefile:SUFFIXES:.
cpp.
cpp~(此行可以放置在makefile的任何位置.
)将以下各行增加到makefile.
缩进的行必须以制表符开头.
.
cpp:$(LINK.
cc)-o$@$$*.
cpp$(LINK.
cc)-o$@$*.
cpp$(LDLIBS).
cpp.
o:$(COMPILE.
cc)$(OUTPUT_OPTION)$$*.
cpp$(COMPILE.
cc)$(OUTPUT_OPTION)$$*.
cpp$(COMPILE.
cc)-o$%$);.
.
.
};因为类名具有外部链接并且所有定义必须是相等的,所以友元函数也必须具有外部链接.
但是,如果使用-features=extensions选项,编译器将接受该代码.
程序员处理该无效代码的方法大概是在类A的实现文件中提供非成员"helper"函数.
可以通过使foo成为静态成员函数得到相同效果.
如果不要客户端调用函数,则可以使该函数私有化.
注–如果使用该扩展,则任何客户端都可以"劫取"您的类.
任何客户端都可以包括类的头文件,然后定义其自身的静态函数foo,该函数将自动成为类的友元.
结果就好像是您使类的所有成员成为了公共的.
4.
10将预定义__func__符号用于函数名使用-features=extensions时,编译器将每个函数中的标识符__func__隐式声明为静态constchar数组.
如果程序使用标识符,编译器还会提供以下定义,其中,function-name是函数原始名称.
类成员关系、名称空间和重载不反映在名称中.
staticconstchar__func__[]="function-name";例如,请考虑以下代码段.
#includevoidmyfunc(void){printf("%s\n",__func__);}每次调用函数时,函数将把以下内容打印到标准输出流.
myfunc4.
9将静态名称空间作用域函数声明为类友元SunStudio12:C++用户指南66程序组织C++程序的文件组织需要比典型的C程序更加小心.
本章说明了如何建立头文件和模板定义.
5.
1头文件创建有效的头文件是很困难的.
头文件通常必须适应C和C++的不同版本.
要提供模板,请确保头文件能容纳多个包含(幂等).
5.
1.
1可适应语言的头文件可能需要开发能够包含在C和C++程序中的头文件.
但是,称为"传统C"的Kernighan和RitchieC(K&C)、ANSIC、AnnotatedReferenceManualC++(ARMC++)以及ISOC++有时要求一个头文件中同一个程序元素有不同的声明或定义.
(有关语言和版本之间的变化的其他信息,请参见《C++迁移指南》.
)要使头文件符合所有这些标准,可能需要根据预处理程序宏__STDC__和__cplusplus的存在情况或值来使用条件编译.
在K&RC中没有定义宏__STDC__,但在ANSIC和C++中都对其进行了定义.
可使用该宏将K&RC代码与ANSIC或C++代码区分开.
该宏最适用于从非原型函数定义中区分原型函数定义.
#ifdef__STDC__intfunction(char*C++&ANSICdeclaration#elseintfunction();//K&RC#endif在C中没有定义宏__cplusplus,但在C++中对其进行了定义.
5第5章67注–早期版本的C++定义了宏c_plusplus,但没有定义cplusplus.
现在已不再定义宏c_plusplus.
可使用__cplusplus宏的定义来区分C和C++.
该宏在保证为函数声明指定extern"C"接口时非常有用,如以下示例所示.
为了防止出现extern"C"指定不一致,切勿将#include指令放在extern"C"链接指定的作用域中.
#include"header.
h"otherincludefiles.
.
.
#ifdefined(__cplusplus)extern"C"{#endifintg1();intg2();intg3()#ifdefined(__cplusplus)}#endif在ARMC++中,__cplusplus宏的值为1.
在ISOC++中,该宏的值为199711L(标准年月用long常量表示).
使用这个宏的值区分ARMC++和ISOC++.
这个宏值在保护模板语法的更改时极为有用.
//templatefunctionspecialization#if__cplusplusintpower(int,int);//ISOC++#endif5.
1.
2幂等头文件头文件应当是幂等的.
也就是说,多次包括头文件的效果和仅包括一次的效果完全相同.
该特性对于模板尤其重要.
通过设置预处理程序条件以防止头文件体多次出现,可以很好的实现幂等.
#ifndefHEADER_H#defineHEADER_H/*contentsofheaderfile*/#endif5.
1头文件SunStudio12:C++用户指南685.
2模板定义可以用两种方法组织模板定义:使用包括的定义和使用独立的定义.
包括的定义组织允许对模板编译进行更多的控制.
5.
2.
1包括的模板定义在将模板的声明和定义放在使用该模板的文件中时,组织是包括定义的组织.
例如:main.
cctemplateNumbertwice(Numberoriginal);templateNumbertwice(Numberoriginal){returnoriginal+original;}intmain(){returntwice(-3);}使用模板的文件包括了包含模板声明和模板定义的文件时,使用模板的该文件的组织也是包括定义的组织.
例如:twice.
h#ifndefTWICE_H#defineTWICE_HtemplateNumbertwice(Numberoriginal);templateNumbertwice(Numberoriginal){returnoriginal+original;}#endifmain.
cc#include"twice.
h"intmain(){returntwice(-3);}注–使模板头文件幂等是非常重要的.
(请参见第68页中的"5.
1.
2幂等头文件".
)5.
2.
2独立的模板定义另一种组织模板定义的方法是将定义保留在模板定义文件中,如以下示例所示.
twice.
h5.
2模板定义第5章程序组织69#ifndefTWICE_H#defineTWICE_HtemplateNumbertwice(Numberoriginal);#endifTWICE_Htwice.
cctemplateNumbertwice(Numberoriginal){returnoriginal+original;}main.
cc#include"twice.
h"intmain(){returntwice(-3);}模板定义文件不得包括任何非幂等头文件,而且通常根本不需要包括任何头文件.
(请参见第68页中的"5.
1.
2幂等头文件".
)请注意,并非所有编译器都支持模板的独立定义模型.
一个单独的定义文件作为头文件时,该文件可能会被隐式包括在许多文件中.
因此,它不应该包含任何函数或变量定义(除非这些定义是模板定义的一部分).
一个单独的定义文件可以包含类型定义,包括typedef.
注–尽管通常会使用模板定义文件的源文件扩展名(即.
c、.
C、.
cc、.
cpp、.
cxx或.
c++),但模板定义文件是头文件.
如果需要,编译器会自动包括这些它们.
模板定义文件不应单独编译.
如果将模板声明放置在一个文件中,而将模板定义放置在另一个文件中,则必须仔细考虑如何构造定义文件,如何命名定义文件和如何放置定义文件.
此外也需要向编译器显式指定定义的位置.
有关模板定义搜索规则的信息,请参阅第90页中的"7.
5模板定义搜索".
5.
2模板定义SunStudio12:C++用户指南70创建和使用模板有了模板,就可以采用类型安全方法来编写适用于多种类型的单一代码.
本章介绍了模板的概念和函数模板上下文中的术语,讨论了更复杂的(更强大的)类模板,描述了模板的组成,此外还讨论了模板实例化、缺省模板参数和模板专门化.
本章的结尾部分讨论了模板的潜在问题.
6.
1函数模板函数模板描述了仅用参数或返回值的类型来区分的一组相关函数.
6.
1.
1函数模板声明使用模板之前,请先声明.
以下示例中的声明提供了使用模板所需的足够信息,但没有提供实现模板所需的足够信息.
templateNumbertwice(Numberoriginal);在此示例中,Number是模板参数,它指定模板描述的函数范围.
更具体地说,Number是模板类型参数,在模板定义中使用它表示确定的模板使用位置处的类型.
6.
1.
2函数模板定义如果要声明模板,请先定义该模板.
定义提供了实现模板所需的足够信息.
以下示例定义了在前一个示例中声明的模板.
templateNumbertwice(Numberoriginal){returnoriginal+original;}因为模板定义通常出现在头文件中,所以模板定义必须在多个编译单元中重复.
不过所有的定义都必须是相同的.
该限制称为一次定义规则.
6第6章71编译器不支持函数参数列表中非类型模板参数的表达式,如以下示例所示.
//Expressionswithnon-typetemplateparameters//inthefunctionparameterlistarenotsupportedtemplatevoidfoo(mytypetemplatevoidfoo(inta[I+J]6.
1.
3函数模板用法声明后,模板可以像其他函数一样使用.
它们的使用由命名模板和提供函数参数组成.
编译器可以从函数参数类型推断出模板类型参数.
例如,您可以使用上面声明的模板,具体步骤如下所示.
doubletwicedouble(doubleitem){returntwice(item);}如果模板参数不能从函数参数类型推断出,则调用函数时必须提供模板参数.
例如:templateTfunc();//nofunctionargumentsintk=func();//templateargumentsuppliedexplicitly6.
2类模板类模板描述了一组相关的类或数据类型,它们只能通过类型来区分:整数值、指向(或引用)具有全局链接的变量的指针、其他的组合.
类模板尤其适用于描述通用但类型安全的数据结构.
6.
2.
1类模板声明类模板声明仅提供了类的名称和类的模板参数.
此类声明是不完整的类模板.
以下示例是名为Array类的模板声明,该类可接受任何类型作为参数.
templateclassArray;该模板用于名为String的类,该类接受unsignedint作为参数.
templateclassString;6.
2.
2类模板定义类模板定义必须声明类数据和函数成员,如以下示例所示.
6.
2类模板SunStudio12:C++用户指南72templateclassArray{Elem*data;intsize;public:Array(intsz);intGetSize();Elem&operator[](intidx);};templateclassString{chardata[Size];staticintoverflows;public:String(char*initial);intlength();};与函数模板不同,类模板可以同时有类型参数(如classElem)和表达式参数(如unsignedSize).
表达式参数可以是:具有整型或枚举的值指向对象的指针或到对象的引用指向函数的指针或到函数的引用指向类成员函数的指针6.
2.
3类模板成员定义类模板的完整定义需要类模板函数成员和静态数据成员的定义.
动态(非静态)数据成员由类模板声明完全定义.
6.
2.
3.
1函数成员定义模板函数成员的定义由模板参数专门化后跟函数定义组成.
函数标识符通过类模板的类名称和模板参数限定.
以下示例说明了Array类模板的两个函数成员的定义,该模板中指定了模板参数template.
每个函数标识符都通过模板类名称和模板参数Array限定.
templateArray::Array(intsz){size=sz;data=newElem[size];}templateintArray::GetSize(){returnsize;}该示例说明了String类模板的函数成员的定义.
6.
2类模板第6章创建和使用模板73#includetemplateintString::length(){intlen=0;while(lenString::String(char*initial){strncpy(data,initial,Size);if(length()==Size)overflows++;}6.
2.
3.
2静态数据成员定义模板静态数据成员的定义由后跟变量定义的模板参数专门化组成,在此处变量标识符通过类模板名称和类模板实际参数来限定.
templateintString::overflows=0;6.
2.
4类模板的用法模板类可以在使用类型的任何地方使用.
指定模板类包括了提供模板名称和参数的值.
以下示例中的声明根据Array模板创建int_array变量.
变量的类声明及其一组方法类似于Array模板中的声明和方法,除了Elem替换为int(请参第74页中的"6.
3模板实例化").
Arrayint_array(100);此示例中的声明使用String模板创建short_string变量.
Stringshort_string("hello");需要任何其他成员函数时,您可以使用模板类成员函数.
intx=int_array.
GetSize();intx=short_string.
length();.
6.
3模板实例化模板实例化是生成采用特定模板参数组合的具体类或函数(实例).
例如,编译器生成一个采用Array的类,另外生成一个采用Array的类.
通过用模板参数替换模板类定义中的模板参数,可以定义这些新的类.
在前面"类模板"一节介绍的Array示例中,编译器用int替换所有Elem.
6.
3模板实例化SunStudio12:C++用户指南746.
3.
1隐式模板实例化使用模板函数或模板类时需要实例.
如果这种实例还不存在,则编译器隐式实例化模板参数组合的模板.
6.
3.
2显式模板实例化编译器仅为实际使用的那些模板参数组合而隐式实例化模板.
该方法不适用于构造提供模板的库.
C++提供了显式实例化模板的功能,如以下示例所示.
6.
3.
2.
1模板函数的显式实例化要显式实例化模板函数,请在template关键字后接函数的声明(不是定义),且函数标识符后接模板参数.
templatefloattwice(floatoriginal);在编译器可以推断出模板参数时,模板参数可以省略.
templateinttwice(intoriginal);6.
3.
2.
2模板类的显式实例化要显式实例化模板类,请在template关键字后接类的声明(不是定义),且在类标识符后接模板参数.
templateclassArray;templateclassString;显式实例化类时,所有的类成员也必须实例化.
6.
3.
2.
3模板类函数成员的显式实例化要显式实例化模板类函数成员,请在template关键字后接函数的声明(不是定义),且在由模板类限定的函数标识符后接模板参数.
templateintArray::GetSize();templateintString::length();6.
3.
2.
4模板类静态数据成员的显式实例要显式实例化模板类静态数据成员,请在template关键字后接成员的声明(不是定义),且在由模板类限定的成员标识符后接模板参数.
templateintString::overflows;6.
3模板实例化第6章创建和使用模板756.
4模板组合可以嵌套使用模板.
这种方式尤其适用于在通用数据结构上定义通用函数,与在标准C++库中相同.
例如,模板排序函数可以通过一个模板数组类进行声明:templatevoidsort(Array);并定义为:templatevoidsort(Arraystore){intnum_elems=store.
GetSize();for(inti=0;istore[j]){Elemtemp=store[j];store[j]=store[j-1];store[j-1]=temp;}}上述示例定义了针对预先声明的Array类模板对象的排序函数.
下一个示例说明了排序函数的实际用法.
Arrayint_array(100);//constructanarrayofintssort(int_array);//sortit6.
5缺省模板参数您可以将缺省值赋予类模板(但不是函数模板)的模板参数.
templateclassArray;templateclassString;如果模板参数具有缺省值,则该参数后的所有参数也必须具有缺省值.
模板参数仅能具有一个缺省值.
6.
6模板专门化将某些模板参数组合视为特殊的参数可以提高性能,如以下twice示例所示.
而模板说明可能无法用于其一组可能的参数,如以下sort示例所示.
模板专门化允许您定义实际模板参数给定组合的可选实现.
模板专门化覆盖了缺省实例化.
6.
6.
1模板专门化声明使用模板参数的组合之前,您必须声明专门化.
以下示例声明了twice和sort的专用实现.
6.
4模板组合SunStudio12:C++用户指南76templateunsignedtwice(unsignedoriginal);templatesort(Arraystore);如果编译器可以明确决定模板参数,则您可以省略模板参数.
例如:templateunsignedtwice(unsignedoriginal);templatesort(Arraystore);6.
6.
2模板专门化定义必须定义声明的所有模板专门化.
下例定义了上一节中声明的函数.
templateunsignedtwice(unsignedoriginal){returnoriginaltemplatevoidsort(Arraystore){intnum_elems=store.
GetSize();for(inti=0;i0){char*temp=store[j];store[j]=store[j-1];store[j-1]=temp;}}6.
6.
3模板专门化使用和实例化专门化与其他任何模板一样使用并实例化,除此以外,完全专用模板的定义也是实例化.
6.
6.
4部分专门化在前一个示例中,模板是完全专用的.
也就是说,模板定义了特定模板参数的实现.
模板也可以部分专用,这意味着只有某些模板参数被指定,或者一个或多个参数被限定到某种类型.
生成的部分专门化仍然是模板.
例如,以下代码样本说明了主模板和该模板的完全专门化.
templateclassAprimarytemplatetemplateclassAspecialization以下代码说明了主模板部分专门化的示例.
6.
6模板专门化第6章创建和使用模板77templateclassAExample1templateclassAclassAExample3示例1提供了用于第一个模板参数是int类型的情况的特殊模板定义.
示例2提供了用于第一个模板参数是任何指针类型的情况的特殊模板定义.
示例3提供了用于第一个模板参数是任何类型的指针到指针而第二个模板参数是char类型的情况的特殊模板定义.
6.
7模板问题部分本节描述了使用模板时会遇到的问题.
6.
7.
1非本地名称解析和实例化有时模板定义使用模板参数或模板本身未定义的名称.
如此,编译器解决了封闭模板作用域的名称,该模板可以在定义或实例化点的上下文中.
名称可以在不同的位置具有不同的含义,产生不同的解析.
名称解析比较复杂.
因此,您不应该依赖除一般全局环境中提供的名称外的非本地名称.
也就是说,仅使用在任何地方都用相同方法声明和定义的非本地名称.
在以下示例中,模板函数converter使用了非本地名称intermediary和temporary.
在use1.
cc和use2.
cc中这些名称的定义不同,因此在不同的编译器下可能会生成不同的结果.
为了能可靠地使用模板,所有非本地名称(该示例中为intermediary和temporary)在任何地方都必须有相同的定义.
use_common.
h//CommontemplatedefinitiontemplateTargetconverter(Sourcesource){temporary=(intermediary)source;return(Target)temporary;}use1.
cctypedefintintermediary;inttemporary;#include"use_common.
h"use2.
cctypedefdoubleintermediary;unsignedinttemporary;#include"use_common.
h"6.
7模板问题部分SunStudio12:C++用户指南78一个常见的非本地名称用法是在模板内使用cin和cout流.
有时程序员要将流作为模板参数传递,这时就要引用到全局变量.
但cin和cout在任何地方都必须有相同的定义.
6.
7.
2作为模板参数的本地类型模板实例化系统取决于类型名称,等效于决定哪些模板需要实例化或重新实例化.
因此本地类型用作模板参数时,会导致严重的问题.
小心在代码中也出现类似的问题.
例如:示例6–1本地类型用作模板参数问题的示例array.
htemplateclassArray{Type*data;intsize;public:Array(intsz);intGetSize();};array.
cctemplateArray::Array(intsz){size=sz;data=newType[size];}templateintArray::GetSize(){returnsize;}file1.
cc#include"array.
h"structFoo{intdata;};ArrayFile1Data(10);file2.
cc#include"array.
h"structFoo{doubledata;};ArrayFile2Data(20);在file1.
cc中记录的Foo类型与在file2.
cc中记录的Foo类型不同.
以这种方法使用本地类型会出现错误和意外的结果.
6.
7.
3模板函数的友元声明模板在使用之前必须先声明.
模板的使用由友元声明构成,不是由模板的声明构成.
实际的模板声明必须在友元声明之前.
例如,编译系统尝试链接以下示例中生成的目标文件时,对未实例化的operatortemplateclassarray{intsize;public:array();friendstd::ostream&operator&);};#endifarray.
cc#include#includetemplatearray::array(){size=1024;}templatestd::ostream&operator&rhs){returnoutrhs.
size#include"array.
h"intmain(){std::coutfoo;std::cout&);6.
7模板问题部分SunStudio12:C++用户指南80因为operator的参数,因此必须在声明函数之前声明array.
文件array.
h必须如下所示:#ifndefARRAY_H#defineARRAY_H#include//thenexttwolinesdeclareoperatorclassarray;templatestd::ostream&operator&);templateclassarray{intsize;public:array();friendstd::ostream&operator(std::ostream&,constarray&);};#endif6.
7.
4在模板定义内使用限定名称C++标准要求使用具有限定名的类型,这些限定名取决于要用typename关键字显式标注为类型名称的模板参数.
即使编译器"知道"它应该是一个类型,也是如此.
以下示例中的注释说明了具有要用typename关键字的限定名的类型.
structsimple{typedefinta_type;staticinta_datum;};intsimple::a_datum=0;//notatypetemplatestructparametric{typedefTa_type;staticTa_datum;};templateTparametric::a_datum=0;//notatypetemplatestructexample{statictypenameT::a_typevariable1;//dependentstatictypenameparametric::a_typevariable2;//dependentstaticsimple::a_typevariable3;//notdependent};templatetypenameT::a_type//dependentexample::variable1=0;//notatypetemplatetypenameparametric::a_type//dependent6.
7模板问题部分第6章创建和使用模板81example::variable2=0;//notatypetemplatesimple::a_type//notdependentexample::variable3=0;//notatype6.
7.
5嵌套模板名称由于">>"字符序列解释为右移运算符,因此在一个模板名称中使用另一个模板名称时必须小心.
确保相邻的">"字符之间至少有一个空格.
例如,以下是形式错误的语句:Array>short_string_array(100)right-shift被解释为:Array>short_string_array(100);正确的语法为:Array>short_string_array(100);6.
7.
6引用静态变量和静态函数在模板定义中,编译器不支持引用在全局作用域或名称空间中声明为静态的对象或函数.
如果生成了多个实例,则每个示例引用到了不同的对象,因此违背了单次定义规则(C++标准的3.
2节).
通常的失败指示是链接时丢失符号.
如果想要所有模板实例化共享单一对象,那么请使对象成为已命名空间的非静态成员.
如果想要模板类的每个实例化不同对象,那么请使对象成为模板类的静态成员.
如果希望每个模板函数实例化的对象不同,请使对象成为函数的本地对象.
6.
7.
7在同一目录中使用模板生成多个程序如果要通过指定-instances=extern生成多个程序或库,建议在不同的目录中生成这些程序或库.
如果要在同一目录中生成多个程序,那么您需要清除不同生成程序之间的系统信息库.
这样可以避免出现任何不可预料的错误.
有关更多信息,请参见第90页中的"7.
4.
4共享模板系统信息库".
请参阅以下包含make文件a.
cc、b.
cc、x.
h和x.
cc的示例.
请注意,仅当指定了-instances=extern时,此示例才有意义:.
.
.
.
.
.
.
.
Makefile.
.
.
.
.
.
.
.
6.
7模板问题部分SunStudio12:C++用户指南82CCC=CCall:aba:$(CCC)-I.
-instances=extern-ca.
cc$(CCC)-instances=extern-oaa.
ob:$(CCC)-I.
-instances=extern-cb.
cc$(CCC)-instances=extern-obb.
oclean:/bin/rm-rfSunWS_cache*.
oab.
.
.
x.
h.
.
.
templateclassX{public:intopen();intcreate();staticintvariable;};.
.
.
x.
cc.
.
.
templateintX::create(){returnvariable;}templateintX::open(){returnvariable;}templateintX::variable=1;.
.
.
a.
cc.
.
.
#include"x.
h"intmain(){Xtemp1;temp1.
open();6.
7模板问题部分第6章创建和使用模板83temp1.
create();}.
.
.
b.
cc.
.
.
#include"x.
h"intmain(){Xtemp1;temp1.
create();}如果同时生成了a和b,请在两个生成之间添加makeclean.
以下命令会引起错误:example%makeaexample%makeb以下命令不会产生任何错误:example%makeaexample%makecleanexample%makeb6.
7模板问题部分SunStudio12:C++用户指南84编译模板C++编译器在模板编译方面处理的工作要比传统UNIX编译器处理的工作多.
C++编译器必须按需为模板实例生成目标代码.
该编译器会使用模板系统信息库在多个独立的编译间共享模板实例,此外还接受某些模板编译选项.
编译器必须在各个源文件中定位模板定义,并维护模板实例和主线代码之间的一致性.
7.
1冗余编译如果使用标志-verbose=template,C++编译器会在编译模板期间通知重要事件.
但如果使用缺省值-verbose=no%template,编译器不会发出通知.
+w选项可以在进行模板实例化时提供其他有关潜在问题的指示信息.
7.
2系统信息库管理CCadmin(1)命令用于管理模板系统信息库.
例如,程序中的更改会造成某些实例化过度,这样会浪费存储空间.
CCadmin–clean命令(以前是ptclean)清除所有实例化及关联数据.
实例化仅在需要时才重新创建.
7.
2.
1生成的实例为了生成模板实例,编译器将内联模板函数看作内联函数.
编译器像管理其他内联函数一样管理这些内联模板函数,另外本章中的说明不适用于模板内联函数.
7.
2.
2整个类实例化编译器通常是分别实例化各个模板类成员,因此,编译器仅实例化程序中使用的成员.
仅用于调试器的方法会因此而不正常地实例化.
有两种方法确保调试成员可用于调试器.
7第7章85首先,编写使用模板类实例成员(否则无用)的非模板函数,不需要调用该函数.
其次,使用-template=wholeclass编译器选项,该选项指示编译器实例化模板类的所有非模板非内联成员(如果实例化这些相同成员中的任何一个).
ISOC++标准允许开发人员编写模板类,因为并不是所有成员都可以使用模板参数.
只要非法成员未被实例化,程序就仍然完好.
ISOC++标准库使用了这种技术.
但是,-template=wholeclass选项会实例化所有成员,因此不能用于此类使用有问题的模板参数实例化的模板类.
7.
2.
3编译时实例化实例化是C++编译器从模板创建可用的函数或对象的过程.
C++编译器使用了编译时实例化,在编译对模板的引用时强制进行实例化.
编译时实例化的优点是:调试更加简单-错误消息在上下文中出现,从而让编译器完全回溯到引用点.
模板实例化始终保持最新.
包括链接阶段在内的总编译时间减少了.
如果源文件位于不同的目录或您使用了具有模板符号的库,则模板可以多次实例化.
7.
2.
4模板实例的放置和链接从SunC++编译器的5.
5版本开始,实例将被放入特殊的地址区,并且链接程序可以识别并丢弃重复实例.
您可以指示编译器使用五个实例放置和链接方法之一:外部、静态、全局、显式和半显式.
外部实例适用于大多数程序的开发,并且在满足以下条件时可以达到最佳的执行效果:程序中的实例集比较小,但是每个编译单元引用了实例较大的子集.
很少有在多于一个或两个编译单元中引用的实例.
静态,已过时.
请参见以下内容.
缺省的全局实例适用于所有开发,并且在对象引用各种实例时可以达到最佳的执行效果.
显式实例适用于某些需精确控制的应用程序编译环境.
半显式实例对编译环境的控制要求较少,但是生成的目标文件较大,并且使用有限制.
本节讨论了五种实例放置和链接方法.
第74页中的"6.
3模板实例化"中提供了有关生成实例的其他信息.
7.
2系统信息库管理SunStudio12:C++用户指南867.
3外部实例对于外部实例方法,所有实例都放置在模板系统信息库中.
编译器确保只有一个一致的模板实例存在;这些实例既不是未定义的也不是多重定义的.
模板仅在需要时才重新实例化.
对于非调试代码,使用-instances=extern时的所有目标文件的大小总量小于使用-instances=global时的所有目标文件的大小总量.
模板实例接受系统信息库中的全局链接.
实例是使用外部链接从当前编译单元引用的.
注–如果在不同的步骤中进行编译和链接,并且在编译步骤中指定了-instance=extern,则还必须在链接步骤中指定该选项.
这种方法的缺点是更改程序或程序发生重大更改时必须清除缓存.
高速缓存是并行编译的瓶颈,这与使用dmake时一样,因为每次只能有一个编译访问高速缓存.
另外,每个目录内仅能生成一个程序.
决定缓存中是否存在有效的模板实例比直接在主目标文件中创建实例(如果需要,用完后可以丢弃)要花费更长的时间.
可使用-instances=extern选项指定外部链接.
因为实例存储在模板系统信息库中,所以必须使用CC命令将使用外部实例的C++对象链接到程序中.
如果要创建包含了使用的所有模板实例的库,请结合使用CC命令与—xar选项.
而不要使用ar命令.
例如:example%CC–xar-instances=extern–olibmain.
aa.
ob.
oc.
o有关更多信息,请参见表15–3.
7.
3.
1可能的缓存冲突如果指定了-instance=extern,请勿在同一目录中运行不同的编译器版本,以避免可能的高速缓存冲突.
使用-instances=extern模板模型时,请注意:请勿在同一目录中创建不相关的二进制文件.
在同一目录中创建的任何二进制文件(.
o、.
a、.
so、可执行程序)应该相关,因为两个或两个以上目标文件中名称相同的所有对象、函数和类型的定义都相同.
在同一目录中同时运行多个编译是安全的,例如使用dmake时.
与另外一个链接步骤同时运行任何编译或链接步骤是不安全的.
"链接步骤"指创建库或可执行程序的任何操作.
确保makefile中的依赖性不允许任何内容与链接步骤以并行方式运行.
7.
3外部实例第7章编译模板877.
3.
2静态实例注–-instances=static选项已过时.
没有任何理由再使用-instances=static,因为-instances=global现在提供了静态的所有优点而没有其缺点.
以前编译器中提供的该选项用于克服C++5.
5中不存在的问题.
对于静态实例方法,所有实例都被放置在当前编译单元内.
因此,模板在每个重新编译期间重新实例化;这些实例不保存到模板系统信息库.
这种方法的缺点是不遵循语言语义,并且会生成很大的对象和可执行文件.
实例接收静态链接.
这些实例在当前编译单元外部是不可视的或不可用的.
因此,模板可以在多个目标文件中具有相同的实例化.
因为多重实例产生了不必要的大程序,所以对于不可能多重实例化模板的小程序可以使用静态链接.
静态实例的编译速度很快,因此这种方法也适用于修复并继续方式的调试.
(请参见《使用dbx调试程序》.
)注–如果您的程序取决于多个编译单元间的共享模板实例(例如模板类或模板函数的静态数据成员),请勿使用静态实例方法.
否则程序会工作不正常.
可使用—instances=static编译器选项指定静态实例链接.
7.
3.
3全局实例与以前的编译器发行版本不同,本版本的编译器无需保护全局实例的多个副本.
这种方法的优点是通常由其他编译器接受的不正确源代码也能在这种模式中接受.
特别的是,从模板实例内对静态变量的引用是不合法的,但通常是可以接受的.
这种方法的缺点是单个目标文件会很大,原因是多个文件中模板实例有多个副本.
如果编译目标文件以便进行调试时,有些使用了-g选项,而有些没有使用该选项,则很难预测是获得链接到程序中模板实例的调试版本还是非调试版本.
模板实例接收全局链接.
这些实例在当前编译单元外部是可视的和可用的.
可使用—instances=global选项指定全局实例(这是缺省值).
7.
3.
4显式实例在显式实例方法中,仅为显式实例化的模板生成实例.
隐式实例化不能满足该要求.
实例被放置在当前编译单元内.
因此,模板在每个重新编译期间重新实例化,这些模板不保存到模板系统信息库.
7.
3外部实例SunStudio12:C++用户指南88这种方法的优点是拥有最少的模板编译和最小的对象大小.
缺点是您必须手动执行所有的实例化.
模板实例接收全局链接.
这些实例在当前编译单元外部是可视的和可用的.
链接程序识别并丢弃重复项目.
可使用—instances=explicit选项指定显式实例.
7.
3.
5半显式实例使用半显式实例方法时,仅为显式实例化或模板体内隐式实例化的模板生成实例.
那些被显式创建实例所需要的实例将会自动生成.
主线代码中隐式实例化不满足该要求.
实例被放置在当前编译单元内.
因此,模板在每个重新编译期间重新实例化;生成的实例接收全局链接,且不会被保存到模板系统信息库中.
可使用—instances=semiexplicit选项指定半显式实例.
7.
4模板系统信息库模板系统信息库中存储需单独进行编译的模板实例,以便仅在需要时编译模板实例.
模板系统信息库包含了使用外部实例方法时模板实例化所需的所有非源文件.
系统信息库不用于其他种类的实例.
7.
4.
1系统信息库结构缺省情况下,模板系统信息库位于名为SunWS_cache的高速缓存目录中.
缓存目录包含在放置目标文件的目录中.
可以通过设置环境变量SUNWS_CACHE_NAME更改高速缓存目录的名称.
请注意,SUNWS_CACHE_NAME变量值必须是目录名称,而不能是路径名.
这是因为编译器自动将模板缓存目录放置到了目标文件目录下,因此编译器已经具有了路径.
7.
4.
2写入模板系统信息库编译器必须存储模板实例时,编译器将模板实例存储在对应于输出文件的模板系统信息库中.
例如,以下命令行将目标文件写入.
/sub/a.
o,将模板实例写入.
/sub/SunWS_cache中包含的系统信息库中.
如果缓存目录不存在,且编译器需要实例化模板,则编译器将创建目录.
example%CC-osub/a.
oa.
cc7.
4模板系统信息库第7章编译模板897.
4.
3从多模板系统信息库读取编译器从对应于编译器读取的目标文件的模板系统信息库读取.
也就是说,以下命令行从.
/sub1/SunWS_cache和.
/sub2/SunWS_cache中进行读取,并且必要时向.
/SunWS_cache中写入.
example%CCsub1/a.
osub2/b.
o7.
4.
4共享模板系统信息库系统信息库中的模板不得违反ISOC++标准的一次定义规则.
也就是说,使用所有的模板时模板必须具有相同的源.
违反该规则会产生不可预料的行为.
确保不违反该规则的最简单和最保守的方法是在任何一个目录内仅生成一个程序或库.
两个不相关的程序可以使用相同类型的名称或外部名称来表示不同的内容.
如果程序共享模板系统信息库,则模板定义会出现冲突,会产生不可预料的结果.
7.
4.
5通过-instances=extern实现模板实例自动一致如果指定了-instances=extern,模板系统信息库管理器可确保系统信息库中实例的状态与源文件一致且是最新的.
例如,如果使用–g选项编译源文件(调试),则也可以使用–g编译来自数据库中的所需文件.
此外,模板系统信息库会跟踪编译中的更改.
例如,如果设置了—DDEBUG标志来定义名称DEBUG,则数据库中会记录下该信息.
如果在以后的编译中省略该标志,则编译器重新实例化设置依赖性的这些模板.
7.
5模板定义搜索使用独立定义模板组织时,模板定义在当前编译单元不可用,编译器必须搜索该定义.
本节描述了编译器如何找到定义.
定义搜索有些复杂,并且很容易出现错误.
因此如果可能,您应该使用定义包括模板文件组织.
这样有助于避免一起定义搜索.
请参见第69页中的"5.
2.
1包括的模板定义".
注–如果使用-template=no%extdef选项,编译器将不搜索单独的源文件.
7.
5模板定义搜索SunStudio12:C++用户指南907.
5.
1源文件位置约定如果没有随选项文件一起提供的特定方向,则编译器使用Cfront样式的方法来定位模板定义文件.
此方法要求模板定义文件包含的基名与模板声明文件包含的基名相同.
此方法也要求模板定义文件位于当前include路径中.
例如,如果模板函数foo()位于foo.
h中,则匹配的模板定义文件应该命名为foo.
cc或某些其他可识别的源文件扩展名(.
C、.
c、.
cc、.
cpp、.
cxx或.
c++).
模板定义文件必须位于常规的include目录之一中,或位于与其匹配的头文件所在目录中.
7.
5.
2定义搜索路径可以用另外一种方法替代用–I设置的常规搜索路径,即使用选项–ptidirectory指定模板定义文件的搜索目录.
多个-pti标志定义多个搜索目录-即搜索路径.
如果使用-ptidirectory,则编译器在该路径查找模板定义文件并忽略–I标志.
由于–ptidirectory标志会使源文件的搜索规则变得复杂,因此使用–I选项代替–ptidirectory选项.
7.
5.
3诊断有问题的搜索有时,编译器会生成令人费解的警告或错误消息,因为它会查找您不打算编译的文件.
此问题通常是由于某个文件(如foo.
h)包含模板声明,且隐式包含了另一个文件(如foo.
cc).
如果头文件foo.
h有模板声明,则在缺省情况下,编译器将搜索名为foo且有C++文件扩展名(.
C、.
c、.
cc、.
cpp、.
cxx或.
c++)的文件.
如果找到这样的文件,编译器将自动把它包含进来.
有关这些搜索的更多信息,请参见第90页中的"7.
5模板定义搜索".
如果有一个不打算这样处理的文件foo.
cc,有两种解决方法:更改.
h或.
cc文件的名称,以消除名称匹配.
通过指定-template=no%extdef选项禁止自动搜索模板定义文件.
然后必须在代码中显式包含所有模板定义,并且不能使用"独立定义"模型.
7.
5模板定义搜索第7章编译模板9192异常处理本章讨论了C++编译器的异常处理实现.
第110页中的"11.
2在多线程程序中使用异常"中提供了附加信息.
有关异常处理的更多信息,请参见由BjarneStroustrup编著的《TheC++ProgrammingLanguage》第三版(Addison-Wesley出版,1997).
8.
1同步和异步异常异常处理设计用于仅支持同步异常,例如数组范围检查.
同步异常这一术语意味着异常只能源于throw表达式.
C++标准支持具有终止模型的同步异常处理.
终止意味着一旦抛出异常,控制永远不会返回到抛出点.
异常处理没有设计用于直接处理诸如键盘中断等异步异常.
不过,如果小心处理,在出现异步事件时也可以进行异常处理.
例如,要用信号进行异常处理工作,您可以编写设置全局变量的信号处理程序,并创建另外一个例程来定期轮询该变量的值,当该变量值发生更改时抛出异常.
不能从信号处理程序抛出异常.
8.
2指定运行时错误有五个与异常有关的运行时错误消息:没有异常处理程序未预料到的异常抛出异常只能在处理程序中重新抛出在堆栈展开时,析构函数必须处理自身的异常内存不足运行时检测到错误时,错误消息会显示当前异常的类型和这五个错误消息之一.
缺省情况下,会调用预定义的函数terminate(),该函数又会调用abort().
8第8章93编译器使用异常规范中提供的信息来优化代码生成.
例如,禁止不抛出异常的函数表条目,而函数异常规范的运行时检查在任何可能的地方被消除.
8.
3禁用异常如果知道程序中未使用异常,可以使用编译器选项-features=no%except抑制支持异常处理的代码的生成.
该选项的使用可以稍微减小代码的大小,并能加快代码的执行速度.
不过,用禁用的异常编译的文件链接到使用异常的文件时,在用禁用的异常编译的文件中的某些局部对象在发生异常时不会销毁.
缺省情况下,编译器生成支持异常处理的代码.
通常都要启用异常,只有时间和空间的开销是考虑的重要因素时才禁止异常.
注–因为C++标准库dynamic_cast和缺省运算符new要求使用异常,所以在标准模式(缺省模式)下编译时不应禁用异常.
8.
4使用运行时函数和预定义的异常标准头文件提供了C++标准中指定的类和异常相关函数.
仅在标准模式(编译器缺省模式,或使用选项-compat=5)下编译时才可访问该头文件.
以下摘录的部分代码显示了头文件声明.
//standardheadernamespacestd{classexception{exception()throw();exception(constexception&)throw();exception&operator=(constexception&)throw();virtual~exception()throw();virtualconstchar*what()constthrow();};classbad_exception:publicexception{.
.
.
};//Unexpectedexceptionhandlingtypedefvoid(*unexpected_handler)();unexpected_handlerset_unexpected(unexpected_handler)throw();voidunexpected();//Terminationhandlingtypedefvoid(*terminate_handler)();terminate_handlerset_terminate(terminate_handler)throw();voidterminate();booluncaught_exception()throw();}8.
3禁用异常SunStudio12:C++用户指南94标准类exception是所选语言构造或C++标准库抛出的所有异常的基类.
可以构造、复制及销毁类型为exception的对象,而不会生成异常.
虚拟成员函数what()返回描述异常的字符串.
为了与C++4.
2版中所用的异常兼容,还提供了头文件以用于标准模式.
该头文件允许转换到标准C++代码,并包含了不是标准C++部分的声明.
应在开发进度计划许可的情况下,更新代码以遵循C++标准(使用而非).
//header,usedfortransition#include#includeusingstd::exception;usingstd::bad_exception;usingstd::set_unexpected;usingstd::unexpected;usingstd::set_terminate;usingstd::terminate;typedefstd::exceptionxmsg;typedefstd::bad_exceptionxunexpected;typedefstd::bad_allocxalloc;在兼容模式(—compat[=4])下,头文件不可用,头文件指随C++4.
2版提供的相同头文件.
此处不再重述.
8.
5将异常与信号和Setjmp/Longjmp混合使用可以在会出现异常的程序中使用setjmp/longjmp函数,只要它们不会互相影响.
使用异常和setjmp/longjmp的所有规则分别适用.
此外,仅当在点A抛出与在点B捕获的异常具有相同的效果时,从点A到点B的longjmp才有效.
具体来说,不得使用longjmp进入或跳出try块或catch块(直接或间接),或使用longjmp跳过自动变量或临时变量的初始化或non-trivial销毁.
不能从信号处理程序抛出异常.
8.
6生成具有异常的共享库切勿将-Bsymbolic与包含C++代码的程序一起使用,应改用链接程序映射文件.
如果使用-Bsymbolic,不同模块中的引用会绑定到应是一个全局对象内容的不同副本.
异常机制依赖对地址的比较.
如果您具有某项内容的两个副本,它们的地址就不等同且异常机制可能失败,这是由于异常机制依赖对假设为唯一地址内容的比较.
如果是使用dlopen打开共享库,必须使用RTLD_GLOBAL,异常才能生效.
8.
6生成具有异常的共享库第8章异常处理9596强制类型转换操作本章讨论C++标准中较新的强制类型转换运算符:const_cast、reinterpret_cast、static_cast和dynamic_cast.
强制类型转换可以将对象或值从一种类型强制转换为另一种类型.
这些强制类型转换操作比以前的强制类型转换操作更好控制.
dynamic_cast运算符提供了一种检查指向多态类的指针的实际类型的方法.
可以用文本编辑器搜索所有新式强制类型转换(搜索_cast),而查找旧式强制类型转换需要进行语法分析.
否则,新的强制类型转换全部执行传统强制类型转换符号允许的强制类型转换子集.
例如,const_cast(v)可以写为(int*)v.
新的强制类型转换仅将各种可用的操作分类以更清楚地表示您的意图,并允许编译器提供更完善的检查.
强制类型转换运算符是始终启用的.
强制类型转换符不能被禁用.
9.
1const_cast可以使用表达式const_cast(v)更改指针或引用的const或volatile限定符.
(在新式强制类型转换中,只有const_cast可以删除const限定符.
)T必须是指针、引用或指向成员的指针类型.
classA{public:virtualvoidf();inti;};externconstvolatileint*cvip;externint*ip;voiduse_of_const_cast(){constAa1;9第9章97const_cast(a1).
f();//removeconstip=const_cast(cvip);//removeconstandvolatile}9.
2reinterpret_cast表达式reinterpret_cast(v)用于更改对表达式v值的解释.
该表达式可用于在指针和整型之间,在不相关的指针类型之间,在指向成员的指针类型之间,和在指向函数的指针类型之间转换类型.
使用reinterpret_cast运算符可能会得到未定义的结果或实现相关结果.
以下几点描述了唯一确定的行为:指向数据对象或函数的指针(但不是指向成员的指针)可以转换为足够包含该指针的任何整型.
(long类型总是足以包含C++编译器支持的体系结构上的指针值.
)转换回原始类型时,指针值将与原始指针值相比较.
指向(非成员)函数的指针可以转换为指向不同(非成员)函数类型的指针.
如果转换回原始类型,指针值将与原始指针相比较.
假设新类型的对齐要求没有原始类型严格,则指向对象的指针可以转换为指向不同对象类型的指针.
转换回原始类型时,指针值将与原始指针值相比较.
如果可以使用重新解释的强制类型转换将"指向T1的指针"类型的表达式转换为"指向T2的指针"类型的表达式,则T1类型左值可以转换为"对T2的引用"类型.
如果T1和T2都是函数类型或都是对象类型,则"指向T1类型的X的成员的指针"类型右值可以显式转换为"指向T2类型的Y的成员的指针"类型右值.
在所有允许的情况下,空指针类型转换为不同的空指针类型后仍然是空指针.
reinterpret_cast运算符不能用来删除const,可使用const_cast来实现.
reinterpret_cast运算符不能用来在指向同一类分层结构中不同类的指针之间进行转换,可使用静态或动态强制类型转换来实现.
(reinterpret_cast不执行所需的调整.
)这一点在以下示例中描述:classA{inta;public:A();};classB:publicA{intb,c;};voiduse_of_reinterpret_cast(){Aa1;longl=reinterpret_cast(&a1);A*ap=reinterpret_cast(l);//safeB*bp=reinterpret_cast(&a1);//unsafeconstAa2;ap=reinterpret_cast(&a2);//error,constremoved}9.
2reinterpret_castSunStudio12:C++用户指南989.
3static_cast表达式static_cast(v)用于将表达式v的值转换为类型T.
该表达式可用于任何隐式允许的转换类型.
此外,任何值的类型都可以强制转换为void,并且,如果强制类型转换与旧式强制类型转换一样合法,则任何隐式转换都可以反向执行.
classB{.
.
.
};classC:publicB{.
.
.
};enumE{first=1,second=2,third=3};voiduse_of_static_cast(C*c1){B*bp=c1;//implicitconversionC*c2=static_cast(bp);//reverseimplicitconversioninti=second;//implicitconversionEe=static_cast(i);//reverseimplicitconversion}static_cast运算符不能用于删除const.
可以使用static_cast对分层结构"向下"强制类型转换(从基到派生的指针或引用),但是不会检查转换,因此结果可能无法使用.
static_cast不能用于从虚拟基类向下强制类型转换.
9.
4动态强制类型转换指向类的指针(或引用)可以实际指向(引用)从该类派生的任何类.
有时希望指向完全派生类的指针,或指向完整对象的某些其他子对象.
动态强制类型转换可以实现这些功能.
注–在兼容模式(-compat[=4])下编译时,如果程序使用动态强制类型转换,则必须使用-features=rtti进行编译.
动态强制类型转换可将指向一个类T1的指针(或引用)转换到指向另一个类T2的指针(或引用).
T1和T2必须属于同一分层结构,类必须是可访问的(通过公共派生),并且转换必须明确.
此外,除非转换是从派生类到其一个基类,否则,包括T1和T2的分层结构的最小部分必须是多态的(至少有一个虚函数).
在表达式dynamic_cast(v)中,v是要进行强制类型转换的表达式,T是要转换到的类型.
T必须是指向完整类的类型(其定义可见)的指针或引用,或指向cvvoid(其中cv是空字符串)、const、volatile或constvolatile的指针.
9.
4.
1将分层结构向上强制类型转换对分层结构进行向上强制类型转换时,如果T指向(或引用)v所指向(引用)类型的基类,则该转换等效于static_cast(v).
9.
4动态强制类型转换第9章强制类型转换操作999.
4.
2强制类型转换到void*如果T是void*,则结果是指向完整对象的指针.
也就是说,v可能指向某完整对象的其中一个基类.
在这种情况下,dynamic_cast(v)的结果如同将v沿分层结构向下转换到完整对象(无论什么对象)的类型,然后转换到void*.
强制类型转换到void*时,分层结构必须是多态的(有虚函数).
9.
4.
3将分层结构向下或交叉强制类型转换向下或交叉强制类型转换分层结构时,分层结构必须是多态的(具有虚函数).
结果在运行时检查.
对分层结构向下或交叉强制类型转换时,有时不能从v转换到T.
例如,尝试的转换可能不明确,T可能无法访问,或v可能未指向(或引用)必要类型的对象.
如果运行时检查失败且T是指针类型,则强制类型转换表达式的值是T类型的空指针.
如果T是引用类型,不会返回任何值(没有C++中的空引用),并且会抛出标准异常std::bad_cast.
例如,此公共派生的示例成功:#include#include//forNULLclassA{public:virtualvoidf();};classB{public:virtualvoidg();};classAB:publicvirtualA,publicB{};voidsimple_dynamic_casts(){ABab;B*bp=&ab;//nocastsneededA*ap=&ab;AB&abr=dynamic_cast(*bp);//succeedsap=dynamic_cast(bp);assert(ap!
=NULL);bp=dynamic_cast(ap);assert(bp!
=NULL);ap=dynamic_cast(&abr);assert(ap!
=NULL);bp=dynamic_cast(&abr);assert(bp!
=NULL);}但此示例失败,因为基类B不可访问.
#include#include//forNULL#include9.
4动态强制类型转换SunStudio12:C++用户指南100classA{public:virtualvoidf(){}};classB{public:virtualvoidg(){}};classAB:publicvirtualA,privateB{};voidattempted_casts(){ABab;B*bp=(B*)&ab;//C-stylecastneededtobreakprotectionA*ap=dynamic_cast(bp);//fails,Bisinaccessibleassert(ap==NULL);try{AB&abr=dynamic_cast(*bp);//fails,Bisinaccessible}catch(conststd::bad_cast&){return;//failedreferencecastcaughthere}assert(0);//shouldnotgethere}如果在一个单独的基类中存在虚拟继承和多重继承,那么实际动态强制类型转换必须能够识别出唯一的匹配.
如果匹配不唯一,则强制类型转换失败.
例如,假定有如下附加类定义:classAB_B:publicAB,publicB{};classAB_B__AB:publicAB_B,publicAB{};示例:voidcomplex_dynamic_casts(){AB_B__ABab_b__ab;A*ap=&ab_b__ab;//okay:findsuniqueAstaticallyAB*abp=dynamic_cast(ap);//fails:ambiguousassert(abp==NULL);//STATICERROR:AB_B*ab_bp=(AB_B*)ap;//notadynamiccastAB_B*ab_bp=dynamic_cast(ap);//dynamiconeisokayassert(ab_bp!
=NULL);}dynamic_cast返回的空指针错误可用作两个代码体之间的条件,一个用于类型确定正确时处理强制类型转换,另一个用于类型确定错误时处理强制类型转换.
voidusing_dynamic_cast(A*ap){if(AB*abp=dynamic_cast(ap))9.
4动态强制类型转换第9章强制类型转换操作101{//abpisnon-null,//soapwasapointertoanABobject//goaheadanduseabpprocess_AB(abp);}else{//abpisnull,//soapwasNOTapointertoanABobject//donotuseabpprocess_not_AB(ap);}}在兼容模式(-compat[=4])下,如果尚未使用-features=rtti编译器选项启用运行时类型信息,则编译器将dynamic_cast转换到static_cast并发出警告.
如果禁用了异常,编译器会将dynamic_cast转换到static_cast并发出警告.
(对于引用类型,dynamic_cast要求运行时发现转换无效的情况下抛出异常.
)有关异常的信息,请参见第91页中的"7.
5.
3诊断有问题的搜索".
动态强制类型转换需要比对应的设计模式慢,例如虚函数的转换.
请参见由ErichGamma编著的《DesignPatterns:ElementsofReusableObject-OrientedSoftware》(Addison-Wesley出版,1994).
9.
4动态强制类型转换SunStudio12:C++用户指南102改善程序性能采用编译器易于编译优化的方式编写函数,可以改善C++函数的性能.
有许多关于软件性能的书籍,尤其是关于C++.
例如,TomCargill编著的《C++ProgrammingStyle》(Addison-Wesley出版,1992)、JonLouisBentley编著的《WritingEfficientPrograms》(Prentice-Hall出版,1982)、DovBulka和DavidMayhew合著的《EfficientC++:PerformanceProgrammingTechniques》(Addison-Wesley出版,2000)以及ScottMeyers编著的《EffectiveC++50WaystoImproveYourProgramsandDesigns》第二版(Addison-Wesley出版,1998).
本章不重复这些有价值的信息,而是讨论了主要影响C++编译器的那些性能技术.
10.
1避免临时对象C++函数经常会产生必须创建并销毁的隐式临时对象.
对于重要的类,临时对象的创建和销毁会占用很多处理时间和内存.
C++编译器消除了某些临时类,但是并不能消除所有的临时类.
您编写的函数要将临时对象的数目减少到理解程序所需的最小数目.
这些技术包括:使用显式变量而不使用隐式临时对象,以及使用引用变量而不使用值参数.
另外一种技术是实现和使用诸如+=这样的操作,而非实现和使用只包含+和=的操作.
例如,下面的第一行引入了用于保存a+b结果的临时对象,而第二行则不是.
Tx=a+b;Tx(a);x+=b;10第10章10310.
2使用内联函数使用扩展内联而不使用正常调用时,对小而快速的函数的调用可以更小更快速.
反过来,如果使用扩展内联而不建立分支,则对又长又慢的函数的调用会更大更慢.
另外,只要函数定义更改,就必须重新编译对内联函数的所有调用.
因此,使用内联函数时要格外小心.
如果预计函数定义会更改而且重新编译所有调用程序非常耗时,请不要使用内联函数.
而如果扩展函数内联的代码比调用函数的代码少,或使用函数内联时应用程序执行速度显著提高,则可以使用内联函数.
编译器不能内联所有函数调用,因此要充分利用函数内联,可能需要进行一些源码更改.
可使用+w选项了解何时不会进行函数内联.
在以下情况中,编译器将不会内联函数:函数包含了复杂控制构造,例如循环、switch语句和try/catch语句.
这些函数很少多次执行复杂控制构造.
要内联这种函数,请将函数分割为两部分,里边的部分包含了复杂控制构造,而外边的部分决定了是否调用里边的部分.
即使编译器可以内联完整函数,从函数常用部分中分隔出不常用部分的这种技术也可以改善性能.
内联函数体又大又复杂.
因为对函数体内其他内联函数的调用,或因为隐式构造函数和析构函数调用(通常发生在派生类的构造函数和析构函数中),所以简单函数体可以非常复杂.
对于这种函数,内联扩展很少提供显著的性能改善,所以函数一般不内联.
内联函数调用的参数既大又复杂.
对于内联成员函数调用的对象是内联函数调用的自身这种情况,编译器特别敏感.
要内联具有复杂参数的函数,只需将函数参数计算到局部变量并将变量传递到函数.
10.
3使用缺省运算符如果类定义不声明无参数的构造函数、复制构造函数、复制赋值运算符或析构函数,那么编译器将隐式声明它们.
它们都是调用的缺省运算符.
类似C的结构具有这些缺省运算符.
编译器生成缺省运算符时,可以了解大量关于需要处理的工作和可以产生优良代码的工作.
这种代码通常比用户编写的代码的执行速度快,原因是编译器可以利用汇编级功能的优点,而程序员则不能利用该功能的优点.
因此缺省运算符执行所需的工作时,程序不能声明这些运算符的用户定义版本.
缺省运算符是内联函数,因此内联函数不合适时不使用缺省运算符(请参见上一节).
否则,缺省运算符是合适的:用户编写的无参数构造函数仅为构造函数的基对象和成员变量调用无参数构造函数.
有效的基元类型具有"不进行任何操作"的无参数构造函数.
用户编写的复制构造函数仅复制所有的基对象和成员变量.
用户编写的复制赋值运算符仅复制所有的基对象和成员变量.
10.
2使用内联函数SunStudio12:C++用户指南104用户编写的析构函数可以为空.
某些C++编程手册建议编写类的程序员始终定义所有的运算符,以便该代码的任何读者都能了解该程序员没有忘记考虑缺省运算符的语义.
显然,该建议与以上讨论的优化有冲突.
这种冲突的解决方案是在代码中放置注释以表明类正使用缺省运算符.
10.
4使用值类包括结构和联合在内的C++类通过值来传递和返回.
对于Plain-Old-Data(POD)类,C++编译器需要像C编译器一样传递结构.
这些类的对象直接进行传递.
对于用户定义复制构造函数的类的对象,编译器需要构造对象的副本,将指针传递到副本,并在返回后销毁副本.
这些类的对象间接进行传递.
编译器也可以选择介于这两个需求之间的类.
不过,该选择影响二进制的兼容性,因此编译器对每个类的选择必须保持一致.
对于大多数编译器,直接传递对象可以加快执行速度.
这种执行速度的改善对于小值类(例如复数和概率值)来说尤其明显.
有时为了改善程序执行效率,您可以设计更可能直接传递而不是间接传递的类.
在兼容模式(-compat[=4])下,如果类具有以下任何一项,则间接进行传递:用户定义的构造函数虚函数虚拟基类间接传递的基间接传递的非静态数据成员否则,类被直接传递.
在标准模式(缺省模式)中,如果类具有以下任何一条,则间接传递该类:用户定义的复制构造函数用户定义的析构函数间接传递的基间接传递的非静态数据成员否则,类被直接传递.
10.
4.
1选择直接传递类尽可能直接传递类:只要可能,就使用缺省构造函数,尤其是缺省复制构造函数.
尽可能使用缺省析构函数.
缺省析构函数不是虚拟的,因此具有缺省析构函数的类通常不是基类.
10.
4使用值类第10章改善程序性能105避免使用虚函数和虚拟基.
10.
4.
2在不同的处理器上直接传递类C++编译器直接传递的类(和联合)与C编译器传递结构(或联合)完全相同.
不过,C++结构和联合在不同的体系结构上进行不同的传递.
表10–1在不同体系结构上结构和联合的传递体系结构说明SPARCV7/V8通过在调用方内分配存储并将指针传递到该存储,传递并返回结构和联合.
(也就是说,所有的结构和联合都通过引用传递.
)SPARCV9不超过16个字节(32个字节)的结构在寄存器中传递.
通过在调用方内分配存储并将指针传递到该存储,联合和所有其他结构将被传递并返回.
(也就是说,小的结构在寄存器中传递,而联合和大的结构通过引用传递.
)因此,小值类与基元类具有相同的传递效率.
x86平台结构和联合通过在堆栈上分配空间并将参数复制到堆栈上来传递.
通过在调用程序的帧中分配临时对象并将临时对象的地址作为隐式的第一个参数传递,返回结构和联合.
10.
5缓存成员变量访问成员变量是C++成员函数的通用操作.
编译器必须经常通过this指针从内存装入成员变量.
因为值通过指针装入,所以编译器有时不能决定何时执行第二次装入或以前装入的值是否仍然有效.
在这些情况下,编译器必须选择安全但缓慢的方法,在每次访问成员变量时重新装入成员变量.
如下所示,可以通过在局部变量中显式缓存成员变量的值来避免不必要的内存重新装入:声明局部变量并使用成员变量的值初始化该变量.
在函数中成员变量的位置使用局部变量.
如果局部变量变化,那么将局部变量的最终值赋值到成员变量.
不过,如果成员函数在该对象上调用另一个成员函数,那么该优化会产生不可预料的结果.
当值位于寄存器中时,这种优化最有效,而这种情况也与基元类型相同.
基于内存的值的优化也会很有效,因为减少的别名使编译器获得了更多的机会来进行优化.
如果成员变量经常通过引用(显式或隐式)来传递,那么优化可能并没什么效果.
10.
5缓存成员变量SunStudio12:C++用户指南106有时,类的目标语义需要成员变量的显式缓存,例如在当前对象和其中一个成员函数参数之间有潜在别名时.
例如:complex&operator*=(complex&left,complex&right){left.
real=left.
real*right.
real+left.
imag*right.
imag;left.
imag=left.
real*right.
imag+left.
image*right.
real;}会产生不可预料的结果,前提是调用时使用:x*=x;10.
5缓存成员变量第10章改善程序性能107108生成多线程程序本章解释了如何生成多线程程序.
此外,还讨论了异常的使用,解释了如何在线程之间共享C++标准库对象,此外还描述了如何在多线程环境中使用传统(旧的)iostream.
关于多线程的更多信息,请参见《多线程编程指南》、《Tools.
h++用户指南》和《标准C++库用户指南》.
11.
1生成多线程程序C++编译器附带的所有库都是多线程安全的.
如果需要生成多线程应用程序,或者需要将应用程序链接到多线程库,必须使用–mt选项编译和链接程序.
此选项会将–D_REENTRANT传递给预处理程序,并按正确的顺序将–l线程传递给ld.
在兼容模式(–compat[=4])下,–mt选项可确保libthread在libC之前链接.
在标准模式(缺省模式)下,-mt选项可确保libthread在libCrun之前链接.
请勿使用–lthread直接链接应用程序,因为这将导致以错误顺序链接libthread.
以下示例显示了当编译和链接分开进行时,生成多线程应用程序的正确方法:example%CC-c-mtmyprog.
ccexample%CC-mtmyprog.
o以下示例显示了生成多线程应用程序的错误方法:example%CC-c-mtmyprog.
oexample%CCmyprog.
o-lthread/usr/lib/libm.
so.
1libCrun.
so.
1=>/usr/lib/libCrun.
so.
1libthread.
so.
1=>/usr/lib/libthread.
so.
1libc.
so.
1=>/usr/lib/libc.
so.
1libdl.
so.
1=>/usr/lib/libdl.
so.
111.
1.
2与线程和信号一起使用C++支持库C++支持库libCrun、libiostream、libCstd和libC是多线程安全的,但不是异步安全.
这意味着,在多线程应用程序中,支持库中可用的函数不能用于信号处理程序中.
这样做的话将导致死锁状态.
在多线程应用程序的信号处理程序中使用下列内容是不安全的:iostreamnew和delete表达式异常11.
2在多线程程序中使用异常对于多线程而言,当前的异常处理实现是安全的,一个线程中的异常与其他线程中的异常互不影响.
不过,您不能使用异常来进行线程之间的通信;一个线程中抛出的异常不会被其他线程捕获到.
每个线程都可设置其自己的terminate()或unexpected()函数.
在一个线程中调用set_terminate()或set_unexpected()只影响该线程中的异常.
对于任何线程,terminate()的缺省函数是abort()(请参见第93页中的"8.
2指定运行时错误").
11.
2.
1线程取消通过调用pthread_cancel(3T)取消线程会导致销毁栈上的自动(局部非静态)对象,但指定了-noex或-features=no%except时例外.
pthread_cancel(3T)使用的机制与异常相同.
取消线程时,局部析构函数与用户通过pthread_cleanup_push()注册的清除例程交叉执行.
在特定的清除例程注册之后,函数调用的本地对象在例程执行前就被销毁了.
11.
2在多线程程序中使用异常SunStudio12:C++用户指南11011.
3在线程之间共享C++标准库对象C++标准库(libCstd-library=Cstd)是MT安全的(有些语言环境下例外),确保了在多线程环境中库内部正常工作.
但是,您仍需要将各个线程之间要共享的库对象锁定起来.
请参见setlocale(3C)和attributes(5)手册页.
例如,如果实例化字符串,然后创建新的线程并使用引用将字符串传递给线程.
因为要在线程之间显示共享这个字符串对象,所以您必须锁定对于该字符串的写访问.
(库提供的用于完成该任务的工具在下文中会有描述.
)另一方面,如果将字符串按值传递给新线程,即使两个不同的线程中的字符串应用RogueWave的"copyonwrite(写时复制)"技术共享表示,也不必担心锁定.
库将自动处理锁定.
只有当要使对象显式可用于多线程或在线程之间传递引用,以及使用全局或静态对象时,您才需要锁定.
下文描述了C++标准库内部使用的锁定(同步)机制,该机制用于确保在多线程下出现正确的行为.
_RWSTDMutex和_RWSTDGuard这两个同步类提供了实现多线程安全的机制.
_RWSTDMutex类通过下列成员函数提供了与平台无关的锁定机制:voidacquire()-自己获取锁定,即在获得此类锁定之前一致处于阻塞状态.
voidrelease()-自己释放锁定.
class_RWSTDMutex{public:_RWSTDMutex();~_RWSTDMutex();voidacquire();voidrelease();};_RWSTDGuard类是封装有_RWSTDMutex类的对象的公用包装器类.
_RWSTDGuard对象尝试在其构造函数中获取封装的互斥锁(抛出从std::exceptiononerror派生的::thread_error类型的异常),并在析构函数中释放互斥锁(析构函数从来不会抛出异常).
class_RWSTDGuard{public:_RWSTDGuard(_RWSTDMutex&);~_RWSTDGuard();};另外,可以使用宏_RWSTD_MT_GUARD(mutex)(以前的_STDGUARD)有条件地在多线程生成中创建_RWSTDGuard的对象.
该对象保护代码块的其余部分,并在该代码块中定义为可同时被多个线程执行.
在单线程生成中,宏扩展到空表达式中.
11.
3在线程之间共享C++标准库对象第11章生成多线程程序111以下示例说明了这些机制的使用.
#include////Anintegersharedamongmultiplethreads.
//intI;////AmutexusedtosynchronizeupdatestoI.
//_RWSTDMutexI_mutex;////IncrementIbyone.
Usesan_RWSTDMutexdirectly.
//voidincrement_I(){I_mutex.
acquire();//Lockthemutex.
I++;I_mutex.
release();//Unlockthemutex.
}////DecrementIbyone.
Usesan_RWSTDGuard.
//voiddecrement_I(){_RWSTDGuardguard(I_mutex);//AcquirethelockonI_mutex.
--I;////ThelockonIisreleasedwhendestructoriscalledonguard.
//}11.
4在多线程环境中使用传统iostream本节介绍如何将libC和libiostream库的iostream类用于多线程环境的输入输出(input-output,I/O).
另外,还提供了如何通过从iostream类派生来扩展库的功能的示例.
但本节并不是指导如何采用C++编写多线程代码.
此处的讨论只适用于原来的iostream(libC和libiostream),而不适用于libCstd(即新的iostream,它是C++标准库的一部分).
11.
4在多线程环境中使用传统iostreamSunStudio12:C++用户指南112iostream库允许多线程环境中的应用程序使用其接口,以及运行支持的Solaris操作系统版本时使用多线程功能的程序使用其接口.
如果应用程序使用以前版本库的单线程功能,那么该应用程序不会受到影响.
如果库能在有多个线程的环境中正常运行,则该库定义为MT安全的.
通常,此处的"正常"意味着其所有公用函数都是可重入的.
iostream库提供了保护,防止多个线程尝试修改由多个线程共享的对象(即C++类的实例)的状态.
但iostream对象的MT安全作用域仅限于该对象的公共成员函数正在执行的那一段时间.
注–应用程序并不能因为使用libC库中的MT安全对象,而被自动保证为是MT安全的.
应用程序只有按预期那样能够在多线程环境中执行时,才被定义为MT安全的.
11.
4.
1MT安全的iostream库的组织MT安全的iostream库的组织与其他版本的iostream库稍有不同.
库的导出接口指的是iostream类的受保护的公共成员函数以及可用基类集合,这一点与其他版本的库相同;但类的分层结构是不同的.
有关详细信息,请参见第118页中的"11.
4.
2iostream库接口更改".
原来的核心类已重命名,即添加了前缀unsafe_.
表11–1列出了属于iostream软件包核心的类.
表11–1原来的iostream核心类类说明stream_MT多线程安全类的基类.
streambuf缓冲区的基类.
unsafe_ios该类包含各种流类通用的状态变量;例如,错误和格式化状态.
unsafe_istream该类支持从streambuf检索的字符序列的有格式和无格式转换.
unsafe_ostream该类支持存储到streambuf中的字符序列的有格式和无格式转换.
unsafe_iostream该类合并unsafe_istream类和unsafe_ostream类,以便进行双向操作.
每个MT安全的类都是从基类stream_MT派生而来.
每个MT安全的类(除了streambuf外)也都是从现有的unsafe_基类派生而来.
示例如下:classstreambuf:publicstream_MT{.
.
.
};classios:virtualpublicunsafe_ios,publicstream_MT{.
.
.
};classistream:virtualpublicios,publicunsafe_istream{.
.
.
};11.
4在多线程环境中使用传统iostream第11章生成多线程程序113类stream_MT提供了使每个iostream类成为MT安全的类所需的互斥锁,另外,还提供了动态启用和禁用这些锁的功能,以便可以动态更改MT安全属性.
用于I/O转换和缓冲区管理的基本功能划入unsafe_类,为库增加MT安全的功能则划入派生类.
每个类的MT安全版本都包含与unsafe_base类相同的受保护的公共成员函数.
MT安全版本类中的每个成员函数都可用作包装器,它可以锁定对象、调用unsafe_base中的相同函数以及解锁对象.
注–streambuf类不是从非安全的类派生而来的.
streambuf类的受保护的公共成员函数可以通过锁定来重入.
此外还提供了带_unlocked后缀的已解锁版本.
11.
4.
1.
1公共转换例程已向iostream接口添加了一组MT安全的重入公共函数.
用户指定的缓冲区被作为每个函数的附加参数.
这些函数如下所述:表11–2多线程安全的可重入公共函数功能说明char*oct_r(char*buf,intbuflen,longnum,intwidth)将指针返回到用八进制表示数字的ASCII字符串.
非零宽度假定为格式化的字段宽度.
返回值不保证指向用户提供缓冲区的开始部分.
char*hex_r(char*buf,intbuflen,longnum,intwidth)将指针返回到用十六进制表示数字的ASCII字符串.
非零宽度假定为格式化的字段宽度.
返回值不保证指向用户提供缓冲区的开始部分.
char*dec_r(char*buf,intbuflen,longnum,intwidth)将指针返回到用十进制表示数字的ASCII字符串.
非零宽度假定为格式化的字段宽度.
返回值不保证指向用户提供缓冲区的开始部分.
char*chr_r(char*buf,intbuflen,longnum,intwidth)返回指向包含字符chr的ASCII字符串的指针.
如果宽度非零,则字符串包含后跟chr的width个空格.
返回值不保证指向用户提供缓冲区的开始部分.
11.
4在多线程环境中使用传统iostreamSunStudio12:C++用户指南114表11–2多线程安全的可重入公共函数(续)功能说明char*form_r(char*buf,intbuflen,longnum,intwidth)返回由sprintf格式化字符串的指针,其中使用了格式字符串format和其余参数.
缓冲区必须具有足够的空间以包含格式化的字符串.
注–用来确保与早期版本的libC兼容的iostream库的公共转换例程(oct、hex、dec、chr和form)不是MT安全的.
11.
4.
1.
2使用MT安全的libC库进行编译和链接生成使用libC库的iostream类以在多线程环境中运行的应用程序时,应使用-mt选项编译和链接该应用程序的源代码.
此选项可将-D_REENTRANT传递给预处理程序,将-lthread传递给链接程序.
注–请使用-mt(而不是-lthread)与libC和libthread链接.
该选项确保了库的正确链接顺序.
错误使用-lthread可能会导致应用程序无法正常运行.
对于使用iostream类的单线程应用程序,不需要使用特殊的编译器和链接程序选项.
缺省情况下,编译器会与libC库链接.
11.
4.
1.
3MT安全的iostream限制有关iostream库的MT安全性的限制定义意味着,用于iostream的许多编程常用方式在使用共享iostream对象的多线程环境中是不安全的.
检查错误状态要实现MT安全,必须在具有可能导致出现错误的I/O操作的关键区中进行错误检查.
以下示例说明了如何检查错误:示例11–1检查错误状态#includeenumiostate{IOok,IOeof,IOfail};iostateread_number(istream&istr,int&num){stream_lockersl(istr,stream_locker::lock_now);11.
4在多线程环境中使用传统iostream第11章生成多线程程序115示例11–1检查错误状态(续)istr>>num;if(istr.
eof())returnIOeof;if(istr.
fail())returnIOfail;returnIOok;}在此示例中,stream_locker对象sl的构造函数锁定istream对象istr.
在read_number终止时调用的析构函数sl解锁istr.
获取通过上次未格式化输入操作提取的字符要实现MT安全,必须在执行上次输入操作和gcount调用这一期间独占使用istream对象的线程内调用gcount函数.
以下示例说明了对gcount的调用:示例11–2调用gcount#include#includevoidfetch_line(istream&istr,char*line,int&linecount){stream_lockersl(istr,stream_locker::lock_defer);sl.
lock();//lockthestreamistristr>>line;linecount=istr.
gcount();sl.
unlock();//unlockistr.
.
.
}在此示例中,stream_locker类的成员函数lock和unlock定义了程序中的互斥区域.
用户定义的I/O操作要实现MT安全,必须锁定为用户定义类型定义且涉及对各个操作进行特定排序的I/O操作,才能定义关键区.
以下示例说明了用户定义的I/O操作:示例11–3用户定义的I/O操作#include#includeclassmystream:publicistream{//otherdefinitions.
.
.
11.
4在多线程环境中使用传统iostreamSunStudio12:C++用户指南116示例11–3用户定义的I/O操作(续)intgetRecord(char*name,int&id,float&gpa);};intmystream::getRecord(char*name,int&id,float&gpa){stream_lockersl(this,stream_locker::lock_now);*this>>name;*this>>id;*this>>gpa;returnthis->fail()==0;}11.
4.
1.
4减少多线程安全类的性能开销使用此版本的libC库中的MT安全类会导致一些性能开销,即使是单线程应用程序中也是如此,但如果使用libC的unsafe_类,则可避免此开销.
可以使用作用域解析运算符执行基类unsafe_的成员函数,例如:cout.
unsafe_ostream::put('4');cin.
unsafe_istream::read(buf,len);注–unsafe_类不能在多线程应用程序中安全地使用.
可以使cout和cin对象成为不安全对象,然后执行正常操作,而不是使用unsafe_类.
这会稍微降低性能.
以下示例说明了如何使用unsafecout和cin:示例11–4禁用多线程安全#include//disablemt-safetycout.
set_safe_flag(stream_MT::unsafe_object);//disablemt-safetycin.
set_safe_flag(stream_MT::unsafe_object);cout.
put("4');cin.
read(buf,len);iostream对象是MT安全对象时,有互斥锁定保护对象的成员变量.
该锁定给仅在单线程环境中执行的应用程序增加了不必要的开销.
为了提高性能,可以动态地启用或禁用iostream对象的MT安全性.
以下示例使iostream对象成为MT不安全的对象:11.
4在多线程环境中使用传统iostream第11章生成多线程程序117示例11–5切换到多线程不安全fs.
set_safe_flag(stream_MT::unsafe_object);//disableMT-safety.
.
.
.
dovariousi/ooperations可以在多个线程未共享iostream的情况下(例如,在只有一个线程的程序中,或在每个iostream都是线程专用的程序中),在代码中安全地使用MT不安全的流.
如果显式在程序中插入同步,还可以在多个线程共享iostream的环境中安全地使用MT不安全的iostream.
以下示例说明了该技术:示例11–6在多线程不安全的对象中使用同步generic_lock();fs.
set_safe_flag(stream_MT::unsafe_object);.
.
.
dovariousi/ooperationsgeneric_unlock();其中,函数generic_lock和generic_unlock可以是使用诸如互斥锁、信号或读取器/写入器锁定等基元的任何同步机制.
注–libC提供的stream_locker类是实现这一目的首选机制.
有关更多信息,请参见第121页中的"11.
4.
5对象锁定".
11.
4.
2iostream库接口更改本节介绍为使iostream库成为MT安全库而对其所做的接口更改.
11.
4.
2.
1新增类下表列出了已增加到libC接口的新类.
示例11–7新增类stream_MTstream_lockerunsafe_iosunsafe_istreamunsafe_ostreamunsafe_iostreamunsafe_fstreambaseunsafe_strstreambase11.
4在多线程环境中使用传统iostreamSunStudio12:C++用户指南11811.
4.
2.
2新增类的分层结构下表列出了已增加到iostream接口的新类的分层结构.
示例11–8新增类的分层结构classstreambuf:publicstream_MT{.
.
.
};classunsafe_ios{.
.
.
};classios:virtualpublicunsafe_ios,publicstream_MT{.
.
.
};classunsafe_fstreambase:virtualpublicunsafe_ios{.
.
.
};classfstreambase:virtualpublicios,publicunsafe_fstreambase{.
.
.
};classunsafe_strstreambase:virtualpublicunsafe_ios{.
.
.
};classstrstreambase:virtualpublicios,publicunsafe_strstreambase{.
.
.
};classunsafe_istream:virtualpublicunsafe_ios{.
.
.
};classunsafe_ostream:virtualpublicunsafe_ios{.
.
.
};classistream:virtualpublicios,publicunsafe_istream{.
.
.
};classostream:virtualpublicios,publicunsafe_ostream{.
.
.
};classunsafe_iostream:publicunsafe_istream,publicunsafe_ostream{.
.
.
};11.
4.
2.
3新增函数下表列出了已增加到iostream接口的新函数.
示例11–9新函数classstreambuf{public:intsgetc_unlocked();voidsgetn_unlocked(char*,int);intsnextc_unlocked();intsbumpc_unlocked();voidstossc_unlocked();intin_avail_unlocked();intsputbackc_unlocked(char);intsputc_unlocked(int);intsputn_unlocked(constchar*,int);intout_waiting_unlocked();protected:char*base_unlocked();char*ebuf_unlocked();intblen_unlocked();char*pbase_unlocked();char*eback_unlocked();char*gptr_unlocked();char*egptr_unlocked();char*pptr_unlocked();voidsetp_unlocked(char*,char*);11.
4在多线程环境中使用传统iostream第11章生成多线程程序119示例11–9新函数(续)voidsetg_unlocked(char*,char*,char*);voidpbump_unlocked(int);voidgbump_unlocked(int);voidsetb_unlocked(char*,char*,int);intunbuffered_unlocked();char*epptr_unlocked();voidunbuffered_unlocked(int);intallocate_unlocked(int);};classfilebuf:publicstreambuf{public:intis_open_unlocked();filebuf*close_unlocked();filebuf*open_unlocked(constchar*,int,int=filebuf::openprot);filebuf*attach_unlocked(int);};classstrstreambuf:publicstreambuf{public:intfreeze_unlocked();char*str_unlocked();};unsafe_ostream&endl(unsafe_ostream&);unsafe_ostream&ends(unsafe_ostream&);unsafe_ostream&flush(unsafe_ostream&);unsafe_istream&ws(unsafe_istream&);unsafe_ios&dec(unsafe_ios&);unsafe_ios&hex(unsafe_ios&);unsafe_ios&oct(unsafe_ios&);char*dec_r(char*buf,intbuflen,longnum,intwidth)char*hex_r(char*buf,intbuflen,longnum,intwidth)char*oct_r(char*buf,intbuflen,longnum,intwidth)char*chr_r(char*buf,intbuflen,longchr,intwidth)char*str_r(char*buf,intbuflen,constchar*format,intwidth=0);char*form_r(char*buf,intbuflen,constchar*format,.
.
.
)11.
4在多线程环境中使用传统iostreamSunStudio12:C++用户指南12011.
4.
3全局和静态数据全局和多线程应用程序中的静态数据不能在线程间安全共享.
尽管线程独立执行,但它们在进程中共享对全局和静态对象的访问.
如果一个线程修改了这种共享对象,那么进程中的其他线程将观察该更改,使得状态难以维持.
在C++中,类对象(类的实例)靠其成员变量的值来维持状态.
如果类对象被共享,那么该类对象将易于被其他线程更改.
多线程应用程序使用iostream库并包含iostream.
h,在缺省情况下,标准流(cout、cin、cerr和clog)定义为全局共享对象.
由于iostream库是MT安全库,它可在执行iostream对象的成员函数时保护其共享对象的状态不会被其他线程访问或更改.
但对象的MT安全性作用域限于执行该对象的公共成员函数期间.
例如,intc;cin.
get(c);获得get缓冲区中下一个字符,并更新ThreadA中的缓冲区指针.
但如果ThreadA中的下一个指令是另一个get调用,则libC库不能保证返回序列中的下一个字符.
这是因为存在一些问题,例如,ThreadB可能也在ThreadA中所做的两次get调用之间执行了get调用.
更多关于共享对象和多线程问题的处理策略,请参见第121页中的"11.
4.
5对象锁定".
11.
4.
4序列执行通常,使用iostream对象时,一序列I/O操作必须是MT安全的.
例如,如下所示代码:cout#includevoidlock_example(fstream&fs){constintlen=128;charbuf[len];intoffset=48;stream_lockers_lock(fs,stream_locker::lock_now);.
.
.
.
.
//openfilefs.
seekg(offset,ios::beg);fs.
read(buf,len);}在此示例中,stream_locker对象的构造函数定义了每次只能执行一个线程的互斥区域的开始位置.
从函数返回后调用的析构函数定义了互斥区域的结束位置.
stream_locker对象确保了在文件中查找特定偏移和从文件中读取能够同时独立执行,并且在原来的ThreadA读取文件之前,ThreadB不能更改文件偏移.
11.
4在多线程环境中使用传统iostreamSunStudio12:C++用户指南122另一种使用stream_locker对象的方法是显式定义互斥区域.
在以下示例中,为了使I/O操作和后续错误检查独立化,使用了vbstream_locker对象的成员函数lock和unlock调用.
示例11–11令I/O操作和错误检查独立化{.
.
.
stream_lockerfile_lck(openfile_stream,stream_locker::lock_defer);.
.
.
.
file_lck.
lock();//lockopenfile_streamopenfile_stream#includefstream*fp;void*process_rtn(void*){//bodyofsub-threadswhichusesfp.
.
.
}voidmulti_process(constchar*filename,intnumthreads){fp=newfstream(filename,ios::in);//createfstreamobject//beforecreatingthreads.
//createthreadsfor(inti=0;i\n11.
4在多线程环境中使用传统iostreamSunStudio12:C++用户指南124示例11–13以MT安全方式使用iostream对象(续)//wheretagisanintegervalueinaunsignedchar.
//Allowsupto255threadstoberuninthisapplication//isanyprintablecharacters//Becausetagisanintegervaluewrittenaschar,//youneedtouseodtolookattheoutputfile,suggest://od-cout.
file|more#include#include#include#include#includestructthread_args{char*filename;intthread_tag;};constintthread_bufsize=256;//entryroutineforeachthreadvoid*ThreadDuties(void*v){//obtainargumentsforthisthreadthread_args*tt=(thread_args*)v;charibuf[thread_bufsize];//openthreadinputfileifstreaminstr(tt->filename);stream_lockerlockout(cout,stream_locker::lock_defer);while(1){//readalineatatimeinstr.
getline(ibuf,thread_bufsize-1,'\n');if(instr.
eof())break;//lockcoutstreamsothei/ooperationisatomiclockout.
lock();//taglineandsendtocoutcoutthread_tag\n";11.
4在多线程环境中使用传统iostream第11章生成多线程程序125示例11–13以MT安全方式使用iostream对象(续)exit(1);}intnum_threads=argc-1;inttotal_tags=0;//arrayofthread_idsthread_tcreated_threads[thread_bufsize];//arrayofargumentstothreadentryroutinethread_argsthr_args[thread_bufsize];inti;for(i=0;iintmain(){coutintmain(){std::cout而非.
不能在兼容模式下使用.
在兼容模式下,必须在链接时显式请求complex库.
在标准模式下,complex库包括在libCstd中,缺省情况下链接该库.
标准模式下,没有complex.
h头文件.
在C++4.
2中,"complex"是类名称,但在标准C++中,"complex"是模板名称.
不可能提供可使旧的代码不加修改就可工作的typedef.
因此,为使用复数的4.
2版编写的代码需要某些简单的编辑,以便使用标准库.
例如,以下代码是为4.
2版编写的,并将在兼容模式下编译.
//fileex1.
cc(compatibilitymode)#include#includeintmain(){complexx(3,3),y(4,4);complexz=x*y;cout#includeusingstd::complex;intmain(){complexx(3,3),y(4,4);12.
4使用类库第12章使用库135complexz=x*y;std::cout、和与编译器本身以及libCrun紧密相关,不能可靠替换.
库libCrun包含了编译器依赖且不能替换的许多"帮助"函数.
从C继承的17个标准头文件(、、等)与Solaris操作系统和Solaris基本运行时库libc紧密相关,不能可靠替换.
这些头文件的C++版本(、、等)与基本C版本紧密相关,不能可靠替换.
12.
7.
3安装替换库要安装替换库,必须先确定替换头文件的位置和libCstd的替换库.
为方便讨论,假定头文件放置在/opt/mycstd/include中,库放置在/opt/mycstd/lib中.
假定库称为libmyCstd.
a.
(库名最好以"lib"开头.
)12.
7.
4使用替换库每次编译时,都使用-I选项指向头文件的安装位置.
此外,还使用-library=no%Cstd选项防止查找编译器自身版本的libCstd头文件.
例如:example%CC-I/opt/mycstd/include-library=no%Cstd.
.
.
(compile)编译期间,-library=no%Cstd选项防止搜索编译器自身版本的这些头文件所在的目录.
每次执行程序或库链接时,都使用-library=no%Cstd选项防止查找编译器自身的libCstd,使用-L选项指向替换库所在目录,以及使用-l选项指定替换库.
示例:example%CC-library=no%Cstd-L/opt/mycstd/lib-lmyCstd.
.
.
(link)也可以直接使用库的完整路径名,而不使用-L和-l选项.
例如:example%CC-library=no%Cstd/opt/mycstd/lib/libmyCstd.
a.
.
.
(link)12.
7替换C++标准库第12章使用库139链接期间,-library=no%Cstd选项防止链接编译器自身版本的libCstd.
12.
7.
5标准头文件实现C有17个标准头文件(、、等).
这些头文件以Solaris操作系统的一部分提供,位于/usr/include目录中.
C++也有这些头文件,但另外要求在全局名称空间和std名称空间中都有各种声明的名称.
在Solaris操作系统版本8之前的版本中,C++编译器提供了自身版本的这些头文件而不是替换/usr/include目录中的头文件.
C++也有另一个版本的各个C标准头文件(、和等),仅名称空间std中有各种声明的名称.
最后,C++添加了32个自己的标准头文件(、、等).
标准头文件的明显实现将C++源码中找到的名称用作包括的文本文件的名称.
例如,标准头文件(或)可能指某目录中名为string(或string.
h)的文件.
这种明显实现有以下缺点:不能仅搜索头文件,也不能为没有文件名后缀的头文件创建makefile规则.
如果具有名为string的目录或可执行程序,可能会错误地找到该目录或程序而不是标准头文件.
在Solaris8操作系统之前的Solaris操作系统版本上,启用了.
KEEP_STATE时,makefile的缺省依赖性会导致尝试将标准头文件替换为可执行程序.
(没有后缀的文件缺省假定为要生成的程序.
)为了解决这些问题,编译器include目录会包含一个与头文件同名的文件和一个指向它且具有唯一后缀.
SUNWCCh的符号链接(SUNW是所有编译器相关程序包的前缀,CC是C++编译器,h是常用的头文件后缀).
指定后,编译器将其重写为并搜索该名称.
后缀名只能在编译器自己的include目录中找到.
如果这样找到的文件是符号链接(正常情况下),编译器就对链接进行一次引用解除,并将结果(此例中是string)用作错误消息和调试器引用的文件名.
忽略文件的依赖性信息时,编译器使用带后缀的名称.
仅当出现在尖括号中且无需指定任何路径时,17种标准C头文件和32种标准C++头文件的两种格式才会发生名称重写.
如果使用引号来代替尖括号指定任何路径组件或其他某些头文件,就不会有重写发生.
下表说明了通常的情况.
表12–3头文件搜索示例源代码编译器搜索注释string.
SUNWCChC++字符串模板12.
7替换C++标准库SunStudio12:C++用户指南140表12–3头文件搜索示例(续)源代码编译器搜索注释cstring.
SUNWCChCstring.
h的C++版本string.
h.
SUNWCChCstring.
hfcntl.
h不是标准C或C++头文件"string"string双引号,不是尖括号.
.
/string指定的路径如果编译器未找到header.
SUNWCCh,则编译器将重新搜索#include指令中提供的名称.
例如,如果使用指令#include,编译器就尝试查找名为string.
SUNWCCh的文件.
如果搜索失败,编译器就查找名为string的文件.
12.
7.
5.
1替换标准C++头文件由于第140页中的"12.
7.
5标准头文件实现"中介绍的搜索算法,您无需提供第139页中的"12.
7.
3安装替换库"中介绍的SUNWCCh版本的替换头文件.
但是会遇到某些上文所述的问题.
如果这样,建议为每个无后缀的头文件添加后缀为.
SUNWCCh的符号链接.
也就是说,对于文件utility,可以运行命令example%ln-sutilityutility.
SUNWCCh编译器第一次查找utility.
SUNWCCh时,会找到它,而不会和其他名为utility的文件或目录混淆.
12.
7.
5.
2替换标准C头文件不支持替换标准C头文件.
如果仍然希望提供标准头文件的自己的版本,那么建议按以下步骤操作:将所有替换头文件放置在一个目录中.
在该目录中创建指向每个替换头文件的.
SUNWCCh符号链接.
在每次调用编译器时使用-I指令,搜索包含替换头文件的目录.
例如,假设有和的替换.
请将文件stdio.
h和cstdio放在目录/myproject/myhdr中.
在该目录中,运行如下命令:example%ln-sstdio.
hstdio.
h.
SUNWCChexample%ln-scstdiocstdio.
SUNWCCh每次编译时使用-I/myproject/mydir选项.
忠告:如果要替换任何C头文件,就必须成对替换.
例如,如果替换,还应该替换.
12.
7替换C++标准库第12章使用库141替换头文件必须与被替换版本具有相同的效果.
也就是说,各种运行时库(如libCrun、libC、libCstd、libc和librwtool)是使用标准头文件中的定义生成的.
如果替换文件不匹配,那么程序不能工作.
12.
7替换C++标准库SunStudio12:C++用户指南142使用C++标准库当在缺省(标准)模式下编译时,编译器可以访问C++标准指定的整个库.
库组件包括一般称为标准模板库(StandardTemplateLibrary,STL)的库和下列组件.
字符串类数字类标准版本的流I/O类基本内存分配异常类运行时类型信息术语STL没有正式的定义,但是通常理解为包括容器、迭代器以及算法.
以下标准库头的子集可以认为包含了STL.
C++标准库(libCstd)基于RogueWaveTM标准C++库版本2,只能在编译器的缺省模式(-compat=5)下使用,使用-compat[=4]选项时不支持该库.
C++编译器还支持STLport的标准库实现版本4.
5.
3.
libCstd仍是缺省库,STLport的产品只是备选的.
有关更多信息,请参见第156页中的"13.
3STLport".
13第13章143如果需要使用自己的C++标准库版本而非编译器附带的某一版本,可以通过指定-library=no%Cstd选项来实现.
替换与编译器一起发布的标准库是有风险的,不能保证产生预期的结果.
有关更多信息,请参见第138页中的"12.
7替换C++标准库".
有关标准库的详细信息,请参见《标准C++库用户指南》和《标准C++类库参考》.
本书前面部分的"开始之前"中的第21页中的"访问SunStudio文档"包含了有关访问这些文档的信息.
有关C++标准库的可用书籍列表,请参见"开始之前"中的第25页中的"其他公司出版的书籍".
13.
1C++标准库头文件表13–1列出了完整标准库的头文件以及每个头文件的简要介绍.
表13–1C++标准库头文件头文件说明操作容器的标准算法位的固定大小序列数字类型表示复数支持在端点增加和删除的序列预定义异常类文件的流I/O函数对象iostream操纵符iostream基类iostream类的前向声明基本流I/O功能输入I/O流遍历序列的类数字类型的属性排序的序列国际化支持带有键/值对的关联容器专用内存分配器13.
1C++标准库头文件SunStudio12:C++用户指南144表13–1C++标准库头文件(续)头文件说明基本内存分配和释放通用的数字操作输出I/O流支持在头部增加和在尾部删除的序列有唯一键值的关联容器将内存中的字符串用为源或接收器的流I/O支持在头部增加和删除的序列附加的标准异常类iostream的缓冲区类字符序列运行时类型标识比较运算符用于数字编程的值数组支持随机访问的序列13.
2C++标准库手册页表13–2列出了标准库中每个组件的可用文档.
表13–2C++标准库手册页手册页概述Algorithms在容器和序列上执行各种操作的通用算法Associative_Containers排序的容器Bidirectional_Iterators可以读取和写入,并且可以双向遍历容器的迭代器Containers标准模板库(standardtemplatelibrary,STL)集合Forward_Iterators可以读取和写入的前移式迭代器Function_Objects定义了operator()的对象Heap_Operations请参见与make_heap、pop_heap、push_heap和sort_heap对应的条目13.
2C++标准库手册页第13章使用C++标准库145表13–2C++标准库手册页(续)手册页概述Input_Iterators只读的前移式迭代器Insert_Iterators允许迭代器向容器插入元素而非覆盖容器内元素的迭代器适配器Iterators集合遍历和修改的指针泛化Negators用于遍历谓词函数对象检测的函数适配器和函数对象OperatorsC++标准模板库输出的运算符Output_Iterators只写的前移式迭代器Predicates返回布尔(true/false)值或整型值的函数或函数对象Random_Access_Iterators可以读取、写入并随机访问容器的迭代器Sequences组织序列集合的容器Stream_Iterators包括允许直接在流上使用通用算法的ostream和istream的迭代器功能__distance_type确定迭代程序所用距离的类型(已过时)__iterator_category确定迭代程序所属的类别(已过时)__reverse_bi_iterator向后遍历集合的迭代器accumulate将一定范围内的所有元素聚集到单个值中adjacent_difference输出在一定范围内每个相邻元素对之间的差别的序列adjacent_find寻找在序列中相等的第一个相邻元素对advance按特定的距离将迭代器向前或者向后移动(如可能)allocator在标准库容器中用于存储管理的缺省分配器对象auto_ptr一个简单、智能的指针类back_insert_iterator用于在集合末端插入项目的插入迭代器back_inserter用于在集合末端插入项目的插入迭代器basic_filebuf将输入序列或输出序列与文件关联的类basic_fstream支持对命名文件的读取和写入,或者与文件描述符关联的设备的读取和写入basic_ifstream支持从命名文件读取或者从其他与文件描述符关联的设备读取basic_ios一个包含所有流都需要的通用函数的基类13.
2C++标准库手册页SunStudio12:C++用户指南146表13–2C++标准库手册页(续)手册页概述basic_iostream帮助格式化或者翻译由流缓冲区控制的字符序列basic_istream帮助读取或者翻译由流缓冲区控制的序列输入basic_istringstream支持从内存中的数组读取basic_string类对象basic_ofstream支持写入命名文件或者其他与文件描述符关联的设备basic_ostream帮助格式化或者写入由流缓冲区控制的序列输出basic_ostringstream支持写入basic_string类的对象basic_streambuf用于派生便于字符序列控制的各种流缓冲区的抽象基类basic_string处理类似字符实体的模板化类basic_stringbuf将输入或者输出序列与任意字符序列关联basic_stringstream支持在内存中的数组中写入和读取basic_string类对象binary_function创建二元函数对象的基类binary_negate返回二元谓词结果补码的函数对象binary_search对容器中的值执行二元搜索bind1st用于将值绑定到函数对象的模板化实用程序bind2nd用于将值绑定到函数对象的模板化实用程序binder1st用于将值绑定到函数对象的模板化实用程序binder2nd用于将值绑定到函数对象的模板化实用程序bitset用于存储和处理固定大小位序列的模板类和相关函数cerr控制向与中声明的对象stderr关联的无缓冲流缓冲区的输出char_traits具有用于basic_string容器和iostream类的类型和运算的特性类cin控制从与中声明的对象stdin关联的流缓冲区的输入clog控制向与中声明的对象stderr关联的流缓冲区的输出codecvt代码转换侧面13.
2C++标准库手册页第13章使用C++标准库147表13–2C++标准库手册页(续)手册页概述codecvt_byname一个包含以命名语言环境为基础的代码集转换分类工具的侧面collate一个字符串检验、比较和散列侧面collate_byname一个字符串检验、比较和散列侧面compare返回真或假的二元函数或函数对象complexC++复数库copy复制一定范围内的元素copy_backward复制一定范围内的元素count计算容器中满足给定条件的元素的数量count_if计算容器中满足给定条件的元素的数量cout控制向与中声明的对象stdout关联的流缓冲区的输出ctype包括字符分类工具的侧面ctype_byname一个包含以命名语言环境为基础的字符分类工具的侧面deque一个支持随机访问迭代器并支持在开始和结束位置进行高效插入/删除的序列distance计算两个迭代器之间的距离divides返回用第一个参数除以第二个参数所得到的结果equal比较等式的两个范围equal_range在集合中找到最大的子范围,可在该范围中插入一个给定值而无需违反集合排序equal_to如果第一个参数与第二个参数相等就返回真的二元函数对象exception一个支持逻辑和运行时错误的类facets用于封装语言环境功能分类的类系列filebuf将输入序列或输出序列与文件关联的类fill用给定值初始化一个范围fill_n用给定值初始化一个范围find在序列中寻找出现的值find_end在序列中寻找上次出现的子序列13.
2C++标准库手册页SunStudio12:C++用户指南148表13–2C++标准库手册页(续)手册页概述find_first_of在序列中寻找在另一个序列中第一次出现的值find_if在满足特定谓词的序列中寻找第一次出现的值for_each将函数应用于范围内的每个元素fpos保持iostream类的位置信息front_insert_iterator用于在集合起始端插入条目的插入迭代器front_inserter用于在集合起始端插入条目的插入迭代器fstream支持对命名文件的读取和写入,或者与文件描述符关联的设备的读取和写入generate初始化一个具有由值产生器类产生的值的容器generate_n初始化一个具有由值产生器类产生的值的容器get_temporary_buffer基于指针的基元,用于处理内存greater如果第一个参数比第二个参数大就返回真的二元函数对象greater_equal如果第一个参数大于或等于第二个参数就返回真的二元函数对象gslice用于表示数组的通用片的数字数组类gslice_array用于表示valarray的类BLAS片的数字数组类has_facet用于确定语言环境是否具有给定侧面的函数模板ifstream支持从命名文件读取或者从其他与文件描述符关联的设备读取includes已排序序列的一系列基本操作indirect_array用于表示从valarray中所选元素的数字数组类inner_product计算两个范围A和B的内积AXBinplace_merge将两个已排序的序列合并成为一个insert_iterator用于将项目插入集合而非覆盖集合的插入迭代器inserter用于将项目插入集合而非覆盖集合的插入迭代器ios一个包含所有流都需要的通用函数的基类ios_base定义成员类型并维护从它继承的类的数据iosfwd声明输入/输出库模板类并使之专用于宽字符和微型字符isalnum确定字符是字母还是数字13.
2C++标准库手册页第13章使用C++标准库149表13–2C++标准库手册页(续)手册页概述isalpha确定字符是否为字母iscntrl确定字符是否为控制字符isdigit确定字符是否为十进制数字isgraph确定字符是否为图形字符islower确定字符是否为小写形式isprint确定字符是否可打印ispunct确定字符是否为标点符号isspace确定字符是否为空格istream帮助读取或者翻译由流缓冲区控制的序列输入istream_iterator具有istreams迭代器功能的流迭代器istreambuf_iterator从流缓冲区读取为其构造的连续字符istringstream支持从内存中的数组读取basic_string类对象istrstream从内存中的数组读取字符isupper确定字符是否为大写形式isxdigit确定字符是否为十六进制数字iter_swap交换两个位置的值iterator基本的迭代器类iterator_traits返回有关迭代器的基本信息less如果第一个参数比第二个参数小就返回真的二元函数对象less_equal如果第一个参数小于或等于第二个参数就返回真的二元函数对象lexicographical_compare按照字典编排顺序来比较两个范围limits请参阅numeric_limitslist支持双向迭代器的序列locale包含多态侧面集的本地化类logical_and如果两个参数都为真就返回真的二元函数对象logical_not如果参数是假就返回真的一元函数对象13.
2C++标准库手册页SunStudio12:C++用户指南150表13–2C++标准库手册页(续)手册页概述logical_or如果两个参数有一个为真就返回真的二元函数lower_bound确定在已排序容器中元素的第一个有效位置make_heap创建堆map用唯一关键字访问非关键字值的关联容器mask_array给出了valarray的屏蔽视图的数字数组类max查找并返回一对值中的最大值max_element查找一个范围中的最大值mem_fun与指向成员函数的指针相匹配的函数对象,替代全局函数mem_fun1与指向成员函数的指针相匹配的函数对象,替代全局函数mem_fun_ref与指向成员函数的指针相匹配的函数对象,替代全局函数mem_fun_ref1与指向成员函数的指针相匹配的函数对象,替代全局函数merge将两个已排序的序列合并为第三个序列messages消息传送侧面messages_byname消息传送侧面min查找并返回一对值中的最小值min_element查找一个范围中的最小值minus返回用第一个参数减去第二个参数所得到的结果mismatch比较来自两个序列的元素并返回前两个不匹配的元素modulus返回第一个参数除以第二个参数所得到的余数money_get输入的货币格式money_put输出的货币格式moneypunct货币标点格式moneypunct_byname货币标点格式multimap用关键字访问非关键字值的关联容器multiplies用于返回第一个参数与第二个参数相乘结果的二元函数对象.
multiset允许快速访问已保存关键字值的关联容器negate返回其参数负值的一元函数对象13.
2C++标准库手册页第13章使用C++标准库151表13–2C++标准库手册页(续)手册页概述next_permutation生成以排序函数为基础的序列的连续置换not1对一元谓词函数对象进行求反操作的函数适配器not2对一元谓词函数对象进行求反操作的函数适配器not_equal_to如果第一个参数与第二个参数不相等就返回true的二元函数对象nth_element重新排列集合,以使按照排序顺序,低于第n个元素的所有元素位于该元素之前,高于第n个元素的所有元素位于该元素之后num_get输入的数字格式num_put输出的数字格式numeric_limits表示标量类型信息的类numpunct数字标点格式numpunct_byname数字标点格式ofstream支持写入命名文件或者其他与文件描述符关联的设备ostream帮助格式化或者写入由流缓冲区控制的序列输出ostream_iterator流迭代器允许使用具有ostream和istream的迭代器ostreambuf_iterator向从其构造的流缓冲区对象写入连续的字符ostringstream支持写入basic_string类的对象ostrstream写入一个在内存中的数组pair异类值对的模板partial_sort对实体集合排序的模板化算法partial_sort_copy对实体集合排序的模板化算法partial_sum计算一组值的连续部分的和partition将所有满足给定谓词的实体放置在不满足给定谓词的实体后面permutation生成以排序函数为基础的序列的连续置换plus用于返回第一个参数与第二个参数相加结果的二元函数对象pointer_to_binary_function采用指向二元函数的指针的函数对象,替代binary_functionpointer_to_unary_function采用指向函数的指针的函数对象类,替代unary_function13.
2C++标准库手册页SunStudio12:C++用户指南152表13–2C++标准库手册页(续)手册页概述pop_heap从堆中移出最大的元素prev_permutation生成以排序函数为基础的序列的连续置换priority_queue像优先队列一样运行的容器适配器ptr_fun一个与指向某函数的指针对应的过载函数,替换一个函数push_heap将一个新元素放入堆queue像队列一样运行的容器适配器(先入先出)random_shuffle集合的随机混洗元素raw_storage_iterator使基于迭代器的算法能够将结果存入尚未初始化的内存中remove将所需元素移动到容器的前端,并返回一个说明所需元素序列的结束位置的迭代器remove_copy将所需元素移动到容器的前端,并返回一个说明所需元素序列的结束位置的迭代器remove_copy_if将所需元素移动到容器的前端,并返回一个说明所需元素序列的结束位置的迭代器remove_if将所需元素移动到容器的前端,并返回一个说明所需元素序列的结束位置的迭代器replace用新值替换集合中的元素replace_copy用新值替换集合中的元素,并将修改过的序列移入结果replace_copy_if用新值替换集合中的元素,并将修改过的序列移入结果replace_if用新值替换集合中的元素return_temporary_buffer基于指针的基元,用于处理内存reverse反转集合中元素的顺序reverse_copy将集合中元素复制到新集合时反转它们的顺序reverse_iterator向后遍历集合的迭代器rotate将包含第一个元素到第中间减1个元素的部分与包含从中间到最后元素的部分交换rotate_copy将包含第一个元素到第中间减1个元素的部分与包含从中间到最后元素的部分交换search在值(这些值在元素状态时与标明范围内的值相等)的序列中查找子序列13.
2C++标准库手册页第13章使用C++标准库153表13–2C++标准库手册页(续)手册页概述search_n在值(这些值在元素状态时与标明范围内的值相等)的序列中查找子序列set支持唯一关键字的关联容器set_difference构建已排序差集的基本设置操作set_intersection构建已排序交集的基本设置操作set_symmetric_difference构建已排序对称差集的基本设置操作set_union构建已排序并集的基本设置操作slice表示数组的类BLAS片的数字数组类slice_array用于表示valarray的类BLAS片的数字数组类smanip用于实现参数化操纵符的帮助程序类smanip_fill用于实现参数化操纵符的帮助程序类sort对实体集合排序的模板化算法sort_heap将堆转换为已排序的集合stable_partition在保持每组中元素的相对顺序的同时,将所有满足给定谓词的实体放在所有不满足给定谓词的实体之前stable_sort对实体集合排序的模板化算法stack像堆栈一样运行的容器适配器(后入先出)streambuf用于派生便于字符序列控制的各种流缓冲区的抽象基类stringbasic_string、allocator>的typedefstringbuf将输入或者输出序列与任意字符序列关联stringstream支持在内存中的数组中写入和读取basic_string类对象strstream在内存中读取或者写入一个数组strstreambuf将输入序列或者输出序列与微型字符数组(其元素存储任意值)关联swap交换值swap_ranges将一个位置的值与在其他位置的值交换time_get输入的时间格式time_get_byname输入的时间格式,以命名语言环境为基础13.
2C++标准库手册页SunStudio12:C++用户指南154表13–2C++标准库手册页(续)手册页概述time_put输出的时间格式time_put_byname输出的时间格式,以命名语言环境为基础tolower将字符转换为小写形式toupper将字符转换为大写形式transform将操作应用到集合中的一系列值并且存储结果unary_function创建一元函数对象的基类unary_negate返回一元谓词结果补码的函数对象uninitialized_copy使用构造从一个范围向另一个位置复制值的算法uninitialized_fill使用了在集合中设置值的构造算法的算法uninitialized_fill_n使用了在集合中设置值的构造算法的算法unique从一个值范围移除连续的重复值并将得到的唯一值放入结果unique_copy从一个值范围移除连续的重复值并将得到的唯一值放入结果upper_bound确定已排序容器中值的最后一个有效位置use_facet用于获取侧面的模板函数valarray用于数字操作的优化数组类vector支持随机访问迭代器的序列wcerr控制向与中声明的对象stderr关联的无缓冲流缓冲区的输出wcin控制从与中声明的对象stdin关联的流缓冲区的输入wclog控制向与中声明的对象stderr关联的流缓冲区的输出wcout控制向与中声明的对象stdout关联的流缓冲区的输出wfilebuf将输入序列或输出序列与文件关联的类wfstream支持对命名文件的读取和写入,或者与文件描述符关联的设备的读取和写入wifstream支持从命名文件读取或者从其他与文件描述符关联的设备读取wios一个包含所有流都需要的通用函数的基类13.
2C++标准库手册页第13章使用C++标准库155表13–2C++标准库手册页(续)手册页概述wistream帮助读取或者翻译由流缓冲区控制的序列输入wistringstream支持从内存中的数组读取basic_string类对象wofstream支持写入命名文件或者其他与文件描述符关联的设备wostream帮助格式化或者写入由流缓冲区控制的序列输出wostringstream支持写入basic_string类的对象wstreambuf用于派生便于字符序列控制的各种流缓冲区的抽象基类wstringbasic_string和allocator>的typedefwstringbuf将输入或者输出序列与任意字符序列关联13.
3STLport如果要使用替换libCstd的标准库,请使用标准库的STLport实现.
可以使用以下编译器选项关闭libCstd并改用STLport库:-library=stlport4有关更多信息,请参见第232页中的"A.
2.
49-library=l[,l.
.
.
]".
本发行版包括称为libstlport.
a的静态归档文件和称为libstlport.
so的动态库.
决定是否使用STLport实现之前,请先考虑以下信息:STLport是开放源代码产品,并不能保证不同发行版本之间的兼容性.
也就是说,使用后续版本的STLport编译,可能导致使用STLport4.
5.
3编译的应用程序中断.
使用后续版本的STLport编译的二进制文件可能无法与使用STLport4.
5.
3编译的二进制文件链接.
stlport4、Cstd和iostream库都提供了自己的I/O流实现.
如果使用-library选项指定其中多个库,会导致出现不确定的程序行为.
编译器的后续发行版本可能不包括STLport4,只包括更新版本的STLport.
在将来发行版中可能不能使用编译器选项-library=stlport4,但可能会用引用更高STLport版本的选项替换该选项.
Tools.
h++不支持STLport.
13.
3STLportSunStudio12:C++用户指南156STLport与缺省的libCstd是二进制不兼容的.
如果使用标准库的STLport实现,则必须使用选项-library=stlport4编译和链接包括第三方库在内的所有文件.
这意味着存在一些限制,例如,不可同时使用STLport实现和C++区间数学库libCsunimath.
这是因为对libCsunimath编译时使用的是缺省的库头文件而不是STLport.
如果决定使用STLport实现,那么一定要包括代码隐式引用的头文件.
允许标准头文件,但不必要包括另一个标准头文件作为实现的一部分.
如果使用-compat=4编译,则不能使用STLport实现.
13.
3.
1重新分发和支持的STLport库请参见运行时库自述文件,了解可依照"最终用户目标代码许可协议"的条款随您的可执行文件或库重新分发的库和目标文件列表.
此自述文件的C++部分列出该编译器发行版支持的STLport.
so版本.
此自述文件作为已安装产品的一部分.
要查看此自述文件的HTML版本,请将浏览器指向缺省安装目录:file:/opt/SUNWspro/docs/index.
html注–如果产品软件没有安装在缺省目录中,请通过系统管理员获取系统中的等效路径.
因为以下测试示例中的代码将库实现假定为不可移植,所以在该测试示例中不能使用STLport编译.
具体来说,它假定或自动包含,这是无效假定.
#include#includeusingnamespacestd;intmain(){vectorv1(10);vectorv3(v1.
size());for(inti=0;iv2(v1.
size());copy_backward(v1.
begin(),v1.
end(),v2.
end());ostream_iteratoriter(cout,"");copy(v2.
begin(),v2.
end(),iter);cout包含在源代码中.
13.
3STLport第13章使用C++标准库157158使用传统iostream库与C类似,C++没有内建输入或输出语句.
相反,I/O工具是由库提供的.
C++编译器提供了iostream类的传统实现和ISO标准实现.
在兼容模式(-compat[=4])下,传统iostream类包含在libC中.
在标准模式(缺省模式)下,传统iostream类包含在libiostream中.
如果源代码使用传统iostream类,且要在标准模式下编译源代码,请使用libiostream.
如果要在标准模式下使用传统iostream功能,请将iostream.
h头文件包括进来并使用-library=iostream选项进行编译.
标准iostream类只能用于标准模式下,且包含在C++标准库libCstd中.
本章介绍了传统iostream库并提供了其使用示例,但并未完整介绍iostream库.
有关更多详细信息,请参见iostream库手册页.
要访问传统iostream手册页,请键入:man-s3CC4name14.
1预定义的iostream有四个预定义的iostream:cin,连接到标准输入cout,连接到标准输出cerr,连接到标准错误clog,连接到标准错误除了cerr之外,所有预定义的iostream都是完全缓冲的.
请参见第161页中的"14.
3.
1使用iostream进行输出"和第164页中的"14.
3.
2使用iostream进行输入".
14第14章15914.
2iostream交互的基本结构通过将iostream库包括进来,程序可以使用许多输入流或输出流.
每个流都具有某些源或接收器,如下所示:标准输入标准输出标准错误文件字符数组流可以被限定到输入或输出,或同时具有输入和输出.
iostream库使用两个处理层来实现这些流.
较低层实现了序列,即字符的简单流.
这些序列由streambuf类或从其派生的类实现.
较高层对序列执行格式化操作.
这些格式化操作由istream和ostream类实现,这两个类将从streambuf类派生的类型的对象作为成员.
附加类iostream用于执行输入和输出的流.
标准输入、输出和错误由从类istream或ostream派生的特殊类对象处理.
分别从istream、ostream和iostream派生的ifstream、ofstream和fstream类用于处理文件的输入和输出.
分别从istream、ostream和iostream派生的istrstream、ostrstream和strstream类用于处理字符数组的输入和输出.
打开输入或输出流时,要创建其中一种类型的对象,并将流的streambuf成员与设备或文件关联.
通常通过流构造函数执行此关联,因此不用直接使用streambuf.
iostream库为标准输入、标准输出和错误输出预定义了流对象,因此不必为这些流创建自己的对象.
可以使用运算符或iostream成员函数将数据插入流(输出)或从流(输入)提取数据,以及控制插入或提取的数据的格式.
如果要插入和提取新的数据类型(其中一个类),通常需要重载插入和提取运算符.
14.
3使用传统iostream库要使用来自传统iostream库的例程,必须针对所需的库部分将头文件包括进来.
下表对头文件进行了具体描述.
14.
2iostream交互的基本结构SunStudio12:C++用户指南160表14–1iostream例程头文件头文件说明iostream.
h声明iostream库的基本功能.
fstream.
h声明专用于文件的iostream和streambuf.
包括了iostream.
h.
strstream.
h声明字符数组专用的iostream和streambuf.
包括了iostream.
h.
iomanip.
h声明操纵符:在iostream中插入或提取的值有不同的作用.
包括了iostream.
h.
stdiostream.
h(已过时)声明专用于stdio文件的iostream和streambuf.
包括了iostream.
h.
stream.
h(已过时)包括了iostream.
h、fstream.
h、iomanip.
h和stdiostream.
h.
用于兼容C++1.
2版的旧式流.
通常程序中不需要所有这些头文件,而仅包括所需声明的头文件.
在兼容模式(-compat[=4])下,传统iostream库是libC的一部分,它由CC驱动程序自动链接.
在标准模式(缺省模式)下,libiostream包含传统iostream库.
14.
3.
1使用iostream进行输出使用iostream进行的输出通常依赖于重载的左移运算符(#includeclassstring{private:char*data;size_tsize;public://(functionsnotrelevanthere)friendostream&operator>(istream&,string&);};在此示例中,必须将插入运算符和提取运算符定义为友元,因为string类的数据部分是private.
ostream&operator>,可以像插入操作那样将提取操作串接在一起.
例如:cin>>a>>b;该语句从标准输入获得两个值.
与其他重载运算符一样,所用的提取器依赖于a和b的类型(如果a和b的类型不同,则使用两个不同的提取器.
)ios(3CC4)手册页中详细讨论了输入格式以及如何控制输入格式.
通常,前导空白字符(空格、换行符、标签、换页等)被忽略.
14.
3.
3定义自己的提取运算符要输入新的类型时,如同重载输出的插入运算符,请重载输入的提取运算符.
类string定义了其提取运算符,如以下代码示例所示:示例14–1string提取运算符istream&operator>>(istream&istr,string&input){constintmaxline=256;charholder[maxline];istr.
get(holder,maxline,"\n');input=holder;returnistr;}get函数从输入流istr读取字符,并将其存储在holder中,直到读取了maxline-1字符、遇到新行或EOF(无论先发生哪一项).
然后,holder中的数据以空终止.
最后,holder中的字符复制到目标字符串.
按照约定,提取器转换其第一个参数中的字符(此示例中是istream&istr),将其存储在第二个参数(始终是引用),然后返回第一个参数.
因为提取器会将输入值存储在第二个参数中,所以第二个参数必须是引用.
14.
3.
4使用char*提取器此处提及这个预定义的提取器是因为它可能产生问题.
使用方法如下:charx[50];cin>>x;14.
3使用传统iostream库SunStudio12:C++用户指南164该提取器跳过前导空白,提取字符并将其复制到x中,直至遇到另一个空白字符.
最后完成具有终止空(0)字符的字符串.
因为输入会溢出给定的数组,所以要小心操作.
您还必须确保指针指向了分配的存储.
例如,下面列出了一个常见的错误:char*p;//notinitializedcin>>p;因为没有告知存储输入数据的位置,所以会导致程序的终止.
14.
3.
5读取任何单一字符除了使用char提取器外,还可以使用任一形式的get成员函数获取一个字符.
例如:charc;cin.
get(c);//leavescunchangedifinputfailsintb;b=cin.
get();//setsbtoEOFifinputfails注–与其他提取器不同,char提取器不会跳过前导空白.
以下方法可以只跳过空格,并在制表符、换行符或任何其他字符处停止:inta;do{a=cin.
get();}while(a=='');14.
3.
6二进制输入如果需要读取二进制值(如使用成员函数write写入的值),可以使用read成员函数.
以下示例说明了如何使用read成员函数输入原始二进制形式的x,这是先前使用write的示例的反向操作.
cin.
read((char*)&x,sizeof(x));14.
3.
7查看输入可以使用peek成员函数查看流中的下一个字符,而不必提取该字符.
例如:if(cin.
peek()!
=c)return0;14.
3使用传统iostream库第14章使用传统iostream库16514.
3.
8提取空白缺省情况下,iostream提取器会跳过前导空白.
可以关闭跳过标志防止这种情况发生.
以下示例先关闭了cin跳过空白功能,然后将其打开:cin.
unsetf(ios::skipws);//turnoffwhitespaceskipping.
.
.
cin.
setf(ios::skipws);//turnitonagain可以使用iostream操纵符ws从iostream中删除前导空白,而不论是否启用了跳过功能.
以下示例说明了如何从iostreamistr中删除前导空白:istr>>ws;14.
3.
9处理输入错误按照约定,第一个参数为非零错误状态的提取器不能从输入流提取任何数据,且不能清除任何错误位.
失败的提取器至少应该设置一个错误位.
对于输出错误,您应该定期检查错误状态,并在发现非零状态时采取某些操作(诸如终止).
!
运算符测试iostream的错误状态.
例如,如果输入字母字符用于输入,以下代码就会产生输入错误:#include#includevoiderror(constchar*message){cerr>bad;if(!
cin)error("abortedduetoinputerror");cout>dec进行基于10的整型转换.
2ostr>hex进行基于16的整型转换.
6ostr>oct进行基于8的整型转换.
14.
5iostream赋值SunStudio12:C++用户指南170表14–2iostream的预定义操纵符(续)预定义的操纵符说明7istr>>ws提取空白字符(跳过空白),直至找到非空白字符(留在istr中).
8ostr>setbase(n)将转换基数设置为n(仅限于0、8、10和16).
9ostr>setw(n)调用ios::width(n).
将字段宽度设置为n.
10ostr>resetiosflags(i)根据i中设置的位,清除标志位向量.
11ostr>setiosflags(i)根据i中设置的位,设置标志位向量.
12ostr>setfill(c)将填充字符(用于填充字段)设置为c.
13ostr>setprecision(n)将浮点精度设置为n个数字.
要使用预定义的操纵符,必须在程序中包含文件iomanip.
h.
您可以定义自己的操纵符.
操纵符共有两个基本类型:无格式操纵符-采用istream&、ostream&或ios&参数,对流进行操作,然后返回其参数.
参数化操纵符-采用istream&、ostream&或ios&参数以及一个附加参数,对流进行操作,然后返回其流参数.
14.
7.
1使用无格式操纵符无格式操纵符是具有如下功能的函数:执行到流的引用以某种方式操作流返回操纵符的参数由于为iostream预定义了采用(指向)此类函数(的指针)的移位运算符,因此可以在输入或输出运算符序列中放入函数.
移位运算符会调用函数而不是尝试读取或写入值.
例如,下面是将tab插入ostream的tab操纵符:ostream&tab(ostream&os){returnos#includeistream&skipon(istream&is){is.
setf(ios::skipws,ios::skipws);returnis;}istream&skipoff(istream&is){is.
unsetf(ios::skipws);returnis;}.
.
.
intmain(){intx,y;cin>>skipon>>x>>skipoff>>y;return1;}14.
7.
2参数化操纵符iomanip.
h中包含的其中一个参数化操纵符是setfill.
setfill设置用于填写字段宽度的字符.
该操作按照下例所示实现://filesetfill.
cc#include#include//theprivatemanipulatorstaticios&sfill(ios&i,intf){i.
fill(f);returni;}//thepublicapplicator14.
7操纵符SunStudio12:C++用户指南172smanip_intsetfill(intf){returnsmanip_int(sfill,f);}参数化操纵符的实现分为两部分:操纵符.
它使用一个额外的参数.
在上面的代码示例中,采用了额外的int参数.
由于未给这个操纵符函数定义移位运算符,所以您无法将它放至输入或输出操作序列中.
相反,您必须使用辅助函数applicator.
applicator.
它调用该操纵符.
applicator是全局函数,您会为它生成在头文件中可用的原型.
通常操纵符是文件中的静态函数,该文件包含了applicator的源代码.
只有applicator可以调用该操纵符,如果您将操纵符设置为静态,就要使操纵符名称始终位于全局地址空间之外.
头文件iomanip.
h中定义了多个类.
每个类都保存一个操纵符函数的地址和一个参数的值.
manip(3CC4)手册页中介绍了iomanip类.
上面的示例使用了smanip_int类,它是与ios一起使用.
因为该类与ios一起使用,所以也可以与istream和ostream一起使用.
上面的示例还使用了另一个类型为int的参数.
applicator创建并返回类对象.
在上面的代码示例中,类对象是smanip_int,其中包含了操纵符和applicator的int参数.
iomanip.
h头文件定义了用于该类的移位运算符.
如果applicator函数setfill在输入或输出操作序列中,会调用该applicator函数,且其返回一个类.
移位运算符作用于该类,以使用其参数值(存储在类中)调用操纵符函数.
在以下示例中,操纵符print_hex:将输出流设置成十六进制模式.
将long值插入流中.
恢复流的转换模式.
使用类omanip_long的原因是该代码示例仅用于输出,而且操作对象是long而不是int:#include#includestaticostream&xfield(ostream&os,longv){longsave=os.
setf(ios::hex,ios::basefield);os>toFile.
rdbuf();然后源文件被提取到目标中.
两种方法是完全等同的.
14.
11iostream手册页许多C++手册页都介绍了iostream库的详细信息.
下表概述了每个手册页中的内容.
要访问传统iostream库手册页,请键入:example%man-s3CC4name表14–3iostream手册页概述手册页概述filebuf详细介绍了从streambuf派生并专用于文件的类filebuf的公用接口.
有关从类streambuf继承的功能的详细信息,请参见sbufpub(3CC4)和sbufprot(3CC4)手册页.
可通过类fstream使用filebuf类.
fstream详细介绍了类ifstream、ofstream和fstream的专用成员函数,这些类是用于文件的istream、ostream和iostream专用版本.
ios详细介绍了作为iostream的基类的类ios的各个部分.
该类也包含了所有流公共的状态数据.
ios.
intro简要介绍了iostream.
14.
11iostream手册页第14章使用传统iostream库175表14–3iostream手册页概述(续)手册页概述istream详细说明了以下内容:类istream的成员函数,这些函数支持对从streambuf获取的字符进行解释输入格式化归为类ostream的一部分的定位函数某些相关函数相关操纵符manip介绍了iostream库中定义的输入和输出操纵符.
ostream详细说明了以下内容:类ostream的成员函数,这些函数支持对写入streambuf的字符进行解释输出格式化归为类ostream的一部分的定位函数某些相关函数相关操纵符sbufprot介绍了对从类streambuf派生的类进行编码的程序员所需的接口.
有关sbufprot(3CC4)手册页中未讨论的一些公用函数,另请参见sbufpub(3CC4)手册页.
sbufpub详细介绍了类streambuf的公用接口,尤其是streambuf的公用成员函数.
该手册页包含了直接处理streambuf类型的对象所需的信息,或是找到从streambuf派生的类继承的函数所需的信息.
如果要从streambuf派生类,另请参见sbufprot(3CC4)手册页.
ssbuf详细介绍了从streambuf派生并专用于处理字符数组的类strstreambuf的专用公用接口.
有关从类streambuf继承的功能的详细信息,请参见sbufpub(3CC4)手册页.
stdiobuf简要介绍了从streambuf派生并专用于处理stdio文件的stdiobuf类.
有关从类streambuf继承的功能的详细信息,请参见sbufpub(3CC4)手册页.
strstream详细介绍了由从iostream派生并专用于处理字符数组的一组类实现的strstream的专用成员函数.
14.
12iostream术语iostream库说明中常常使用一些与一般编程中的术语类似的术语,但有特殊含义.
下表定义了讨论iostream库时使用的这些术语.
14.
12iostream术语SunStudio12:C++用户指南176表14–4iostream术语iostream术语定义缓冲区该词有两个含义,一个特定于iostream软件包,另一个较常适用于输入和输出.
与iostream库特定相关时,缓冲区是由类streambuf定义的类型的对象.
通常,缓冲区是一个内存块,用于将字符高效传输到输出的输入.
对于已缓冲的I/O,缓冲区已满或被强制刷新之前,字符的实际传输会延迟.
无缓冲的缓冲区是指streambuf,其中没有上文定义的一般意义的缓冲区.
本章中使用的术语"缓冲区"不是指streambuf.
但手册页和其他C++文档中使用的术语"缓冲区"是指streambuf.
提取从iostream获取输入的过程.
Fstream专用于文件的输入或输出流.
特指以courier字体打印时从类iostream派生的类.
插入将输出发送到iostream中的过程.
iostream通常为输入或输出流.
iostream库通过include文件iostream.
h、fstream.
h、strstream.
h、iomanip.
h和stdiostream.
h实现的库.
因为iostream是面向对象的库,所以应扩展该库.
因此,可以对iostream库执行的某些操作并未实现.
流通常是指iostream、fstream、strstream或用户定义的流.
Streambuf包含字符序列的缓冲区,其中字符具有put或get指针(或兼有).
以courier字体打印时,它表示特定类.
否则,通常是指streambuf类或从streambuf派生的类的对象.
任何流对象都包含从streambuf派生的类型的对象或指向对象的指针.
Strstream专用于字符数组的iostream.
它是指以courier字体打印时的特定类.
14.
12iostream术语第14章使用传统iostream库177178使用复数运算库复数是由实部和虚部组成的数.
例如:3.
2+4i1+3i1+2.
3i在特例情况下,如0+3i是纯虚数,通常写为3i;5+0i是纯实数,通常写为5.
可以使用complex数据类型来表示复数.
注–复数运算库(libcomplex)仅可用于兼容模式(-compat[=4])下.
在标准模式(缺省模式)下,C++标准库libCstd中附带具有类似功能的复数类.
15.
1复数库复数运算库以新的数据类型实现复数数据类型,并提供:运算符数学库函数(为内建数字类型定义)扩展(用于允许复数输入和输出的iostream)错误处理机制复数也表示为绝对值(或幅度)和参数(或角度).
该库提供了在实部虚部(笛卡尔)表示形式和幅度角度(极)表示形式之间进行转换的函数.
数字复共轭的虚部中有相反符号.
15.
1.
1使用复数库要使用复数库,应在程序中包含头文件complex.
h,并使用-library=complex选项进行编译和链接.
15第15章17915.
2complex类型复数运算库定义了一个类:complex类.
complex类的对象可以存放一个复数.
复数由两部分构成:实部虚部classcomplex{doublere,im;};complex类的对象值是一对double值.
第一个值表示实部,第二个值表示虚部.
15.
2.
1complex类的构造函数有两个用于complex的构造函数.
它们的定义是:complex::complex(){re=0.
0;im=0.
0;}complex::complex(doubler,doublei=0.
0){re=r;im=i;}如果声明复数变量时没有指定参数,则会使用第一个构造函数并初始化变量,因此两个部分都为0.
以下示例创建了一个其实部和虚部均为0的复数变量.
complexaComp;您可以给定一个或两个参数.
无论是以上哪种情况,都将使用第二个构造函数.
如果只给定一个参数,该参数将作为实部的值,而虚部的值设置为0.
例如:complexaComp(4.
533);用下列值创建一个复数变量:4.
533+0i如果给定了两个值,第一个值被视为实部的值,而第二个值被视为虚部的值.
例如:complexaComp(8.
999,2.
333);用下列值创建一个复数变量:8.
999+2.
333i也可以使用复数运算库中提供的polar函数(请参见第181页中的"15.
3数学函数")创建复数.
polar函数根据给定的极坐标幅度和角度创建复数值.
没有用于complex类型的析构函数.
15.
2complex类型SunStudio12:C++用户指南18015.
2.
2算术运算符复数运算库定义了所有基本的算术运算符.
具体来说,以下运算符按一般方法和普通的优先级工作:减法运算符(-)具有其通常的二元和一元含义.
此外,您可以按通常的方法使用以下运算符:加法赋值运算符(+=)减法赋值运算符(-=)乘法赋值运算符(*=)除法赋值运算符(/=)但是,若将以上四个运算符用于表达式,则不产生任何值.
例如,下列表达式无法进行运算:complexa,b;.
.
.
if((a+=2)==0)illegalb=a*=b;//illegal另外还可以使用等号(==)和不等号(!
=),它们具有常规含义.
将运算表达式中的实数和复数混合时,C++使用复数运算符函数并将实数转换为复数.
15.
3数学函数复数运算库提供了许多数学函数.
一些是专用于复数的,而其余的则是标准C数学库中函数的复数版本.
全部这些函数为每个可能的参数产生结果.
如果函数无法生成具有数学意义的结果,它就调用complex_error并返回适用的某值.
具体来说,这些函数会尽量避免实际的溢出,而是调用complex_error并显示消息.
下表描述了复数运算库函数的提示.
注–sqrt和atan2函数的实现遵循C99csqrt附录G规范.
15.
3数学函数第15章使用复数运算库181表15–1复数运算库函数复数运算库函数说明doubleabs(constcomplex)返回复数的幅度.
doublearg(constcomplex)返回复数的角度.
complexconj(constcomplex)返回其参数的复共轭.
doubleimag(constcomplex&)返回复数的虚部.
doublenorm(constcomplex)返回其参数幅度的平方.
比abs快,但较易产生溢出.
用于比较幅度.
complexpolar(doublemag,doubleang=0.
0)执行一对表示复数幅度和角度的极坐标,并返回对应的复数.
doublereal(constcomplex&)返回复数的实部.
表15–2复数数学函数和三角函数复数运算库函数说明complexacos(constcomplex)返回余弦为其参数的角度.
complexasin(constcomplex)返回正弦为其参数的角度.
complexatan(constcomplex)返回正切为其参数的角度.
complexcos(constcomplex)返回其参数的余切.
complexcosh(constcomplex)返回其参数的双曲余弦.
complexexp(constcomplex)计算e**x,其中e为自然对数的基数,x是为exp提供的参数.
complexlog(constcomplex)返回其参数的自然对数.
complexlog10(constcomplex)返回其参数的常用对数.
complexpow(doubleb,constcomplexexp)complexpow(constcomplexb,intexp)complexpow(constcomplexb,doubleexp)complexpow(constcomplexb,constcomplexexp)使用两个参数:pow(b,exp).
它计算出b的exp次幂.
complexsin(constcomplex)返回其参数的正弦.
complexsinh(constcomplex)返回其参数的双曲正弦.
complexsqrt(constcomplex)返回其参数的平方根.
15.
3数学函数SunStudio12:C++用户指南182表15–2复数数学函数和三角函数(续)复数运算库函数说明complextan(constcomplex)返回其参数的正切.
complextanh(constcomplex)返回其参数的双曲正切.
15.
4错误处理复数库具有以下用于错误处理的定义:externinterrno;classc_exception{.
.
.
};intcomplex_error(c_exception&);外部变量errno是来自C库的全局错误状态.
errno可以为标准头文件errno.
h中所列值(请参见perror(3)手册页).
没有任何函数会将errno设置为零,但有许多函数会将它设置为其他值.
要分辨特定运算是否失败:1.
在运算前将errno设置为零.
2.
测试运算.
函数complex_error采用对类型c_exception的引用并由下列复数运算库函数调用:exploglog10sinhcosh缺省版本的complex_error返回零.
这个零值的返回意味着发生了缺省的错误处理.
可以提供自己的替换函数complex_error,以执行其他错误处理.
cplxerr(3CC4)手册页中介绍了错误处理.
cplxtrig(3CC4)和cplxexp(3CC4)手册页中介绍了缺省的错误处理,下表中也进行了简要介绍.
复数运算库函数缺省错误处理汇总exp如果产生溢出,将errno设置为ERANGE,并返回一个极大的复数.
log、log10如果参数为零,将errno设置为EDOM,并返回一个极大的复数.
15.
4错误处理第15章使用复数运算库183复数运算库函数缺省错误处理汇总sinh、cosh如果参数的虚部产生溢出,则返回一个零复数.
如果实部产生溢出,则返回一个极大的复数.
无论是以上哪种情况,都将errno设置为ERANGE.
15.
5输入和输出复数运算库提供了用于复数的缺省提取器和插入器,如以下示例所示:ostream&operator>(istream&,complex&);//extractor有关提取器和插入器的基本信息,请参见第160页中的"14.
2iostream交互的基本结构"和第161页中的"14.
3.
1使用iostream进行输出".
对于输入,复数提取器>>从输入流中提取一对数(用圆括号括住,并由逗号分隔开),并将其读入复数对象.
第一个值被视为实部的值,而第二个值被视为虚部的值.
例如,给定声明和输入语句:complexx;cin>>x;以及输入(3.
45,5),则x值等于3.
45+5.
0i.
对插入器来讲反向为真.
如果给定complexx(3.
45,5),cout=b;//error:operator>=cannotbeappliedtotypecomplex同样,由于未明确定义概念,因此不会自动将类型complex转换为其他类型.
您可以指定是否需要实部、虚部或幅度.
complexa;doublef(double);f(abs(a));//OKf(a);//error:nomatchforf(complex)15.
7效率设计complex类主要为了提高效率.
最简单的函数声明为inline,以消除函数调用开销.
在函数不同时就会提供函数的多个开销版本.
例如,pow函数有多个版本,分别取类型为double和int以及complex的指数,而前者的运算简单得多.
在包含complex.
h时,会自动包含标准C数学库头文件math.
h.
然后C++开销规则就会产生类似于下面的表达式效率评估:doublex;complexx=sqrt(x);在此示例中,调用了标准数学函数sqrt(double),且结果转换为类型complex,而不是先转换为类型complex再调用sqrt(complex).
该结果转向重载决策规则的外部,正好是您所希望的结果.
15.
7效率第15章使用复数运算库18515.
8复数手册页复数运算库的剩余文档由下表所列的手册页组成:表15–3有关complex类型的手册页手册页概述cplx.
intro(3CC4)对复数运算库的一般性介绍cartpol(3CC4)笛卡尔函数和极函数cplxerr(3CC4)错误处理函数cplxexp(3CC4)指数、对数和平方根函数cplxops(3CC4)算术运算符函数cplxtrig(3CC4)三角函数15.
8复数手册页SunStudio12:C++用户指南186生成库本章解释了如何生成您自己的库.
16.
1认识库库具有两点好处.
首先,它们提供了在多个应用程序间共享代码的方法.
如果您有要共享的代码,则可以创建一个具有该代码的库,并将该库链接到需要这些代码的应用程序.
其次,库提供了降低大型应用程序复杂性的方法.
这类应用程序可以将相对独立的部分生成为库并进行维护,因此减轻程序员在其他部分工作的负担.
生成库只不过是创建.
o文件(使用-c选项编译代码)并使用CC命令将.
o文件并入库中.
可以生成两种库:静态(归档)库和动态(共享)库.
对于静态(归档)库,库中的对象在链接时链接到程序的可执行文件中.
只有库中属于应用程序所需的那些.
o文件链接到可执行文件.
静态(归档)库的名称通常以.
a后缀结尾.
对于动态(共享)库,库中的对象并不链接到程序的可执行文件,而是链接程序在可执行文件中注明程序依赖于库.
执行该程序时,系统会装入程序所需的动态库.
如果使用同一动态库的两个程序同时执行,那么操作系统在程序间共享这个动态库.
动态(共享)库名称以.
so后缀结尾.
动态链接共享库较静态链接归档库有多个优势:可执行文件较小.
在运行时,代码的有效部分可在程序间共享,这样就可以降低内存使用量.
库可以在运行时替换,无需重新链接应用程序.
(动态链接共享库的主要机制是使程序能够利用Solaris操作系统的多项改进的功能,而无需重新链接和分发程序.
)共享库可以在运行时通过使用dlopen()函数调用装入.
但动态库也具有一些缺点:16第16章187运行时链接有执行时间成本.
使用动态库进行程序的分发可能会要求同时分发该程序所使用的库.
将共享库移动到一个不同的位置就可以阻止系统查找该库并执行程序.
(环境变量LD_LIBRARY_PATH有助于解决此问题.
)16.
2生成静态(归档)库生成静态(归档)库的机制与生成可执行文件相似.
对象(.
o)文件集合可以使用CC的–xar选项并入单个库中.
可以使用CC-xar而非直接使用ar命令来生成静态(归档)库.
C++语言通常要求编译器维护的信息比传统.
o文件提供的信息多,尤其是模板实例.
–xar选项可确保所有必要信息(包括模板实例)都包括在库中.
在通常的编程环境下,可能无法完成该操作,因为make无法确定实际创建和引用了哪些模板文件.
如果没有CC-xar,引用的模板实例可能没有按照需要包括在库中.
例如:%CC-cfoo.
cc#Compilemainfile,templatesobjectsarecreated.
%CC-xar-ofoo.
afoo.
o#Gatherallobjectsintoalibrary.
–xar标志会使CC创建静态(归档)库.
要为新建的库命名,需要使用–o指令.
编译器检查命令行上的目标文件,交叉引用这些目标文件与模板系统信息库中的目标文件,并将用户的目标文件所需的模板(以及主目标文件本身)添加到归档文件中.
注–仅可将-xar标志用于创建或更新现有归档文件.
不要用它来维护归档.
-xar选项与ar-cr等效.
最好每个.
o文件中只有一个函数.
如果链接了归档文件,则在需要该归档文件中的.
o文件中的符号时,整个特定.
o文件都链接到应用程序中.
每个.
o文件中有一个函数可以确保将只从归档文件链接应用程序所需的那些符号.
16.
3生成动态(共享)库动态(共享)库的生成方式与静态(归档)库的生成方式基本相同,除了在命令行上使用–G而不是–xar.
不应直接使用ld.
与静态库一样,CC命令可以确保使用模板时,模板系统信息库中所有必要的模板实例都包括在库中.
与应用程序链接的动态库中所有静态构造函数都在执行main()之前调用,所有静态析构函数都在main()退出之后调用.
如果使用dlopen()打开共享库,则所有静态构造函数都在执行dlopen()时执行,所有静态析构函数都在执行dlclose()时执行.
应该使用CC-G来生成动态库.
使用ld(链接编辑器)或cc(C编译器)生成动态库时,异常可能无法生效,且库中定义的全局变量未初始化.
16.
2生成静态(归档)库SunStudio12:C++用户指南188要生成动态(共享)库,必须使用CC的–Kpic或–KPIC选项编译每个对象来创建可重定位的目标文件.
然后您就可以生成一个具有这些可重定位目标文件的动态库.
如果遇到异常的链接失败,可能是忘记了使用–Kpic或–KPIC编译某些对象.
要生成名为libfoo.
so的C++动态库(该库包含源文件lsrc1.
cc和lsrc2.
cc中的对象),请键入:%CC-G-olibfoo.
so-hlibfoo.
so-Kpiclsrc1.
cclsrc2.
cc-G选项指定动态库的构造.
-o选项指定库的文件名.
-h选项指定共享库的名称.
-Kpic选项指定目标文件与位置无关.
注–CC-G命令不会将任何-l选项传递给ld.
如果要使共享库依赖于另一个共享库,必须在命令行上传递必需的-l选项.
例如,如果要使共享库依赖于libCrun.
so,必须在命令行上传递-lCrun.
16.
4生成包含异常的共享库对于包含C++代码的程序,切勿使用-Bsymbolic,而应使用链接程序映射文件.
如果使用-Bsymbolic,不同模块中的引用会绑定到应是一个全局对象内容的不同副本.
异常机制依赖对地址的比较.
如果您具有某项内容的两个副本,它们的地址就不等同且异常机制可能失败,这是由于异常机制依赖对假设为唯一地址内容的比较.
使用dlopen()打开共享库时,必须使用RTLD_GLOBAL,异常才能生效.
16.
5生成专用的库在组织生成一个仅供内部使用的库时,可以使用不建议在一般情况下使用的选项来生成这个库.
具体来说,库不需要符合系统的应用程序二进制接口(applicationbinaryinterface,ABI).
例如,可以使用-fast选项编译库,以提高其在某已知体系结构上的性能.
同样,可以使用-xregs=float选项编译库以提高性能.
16.
6生成公用的库在组织生成一个供其他公司使用的库时,库的管理、平台的一般性以及其他问题就变得尤为重要.
一个用于检验库是否为公用的简单测试就是询问应用程序程序员是否可以轻松地重新编译该库.
生成公用库时应该符合系统的应用程序二进制接口(applicationbinaryinterface,ABI).
通常,这意味着应该避免任何特定于处理器的选项.
(例如,不要使用–fast或–xtarget.
)SPARCABI为应用程序保留了一些专用寄存器.
对于V7和V8,这些寄存器是%g2、%g3和%g4.
对于V9,这些寄存器是%g2和%g3.
由于多数编译用于应用程序,所以在16.
6生成公用的库第16章生成库189缺省情况下,为了提高程序的性能,C++编译器将这些寄存器作为临时寄存器使用.
但是,对公用库中寄存器的使用通常不兼容于SPARCABI.
生成公用库时,请使用-xregs=no%appl选项编译所有对象,以确保不会使用应用程序寄存器.
16.
7生成具有CAPI的库如果要生成用C++编写且可用于C程序的库,必须创建CAPI(applicationprogramminginterface,应用程序编程接口).
为此,应先使所有导出的函数为extern"C".
注意,只有在全局函数中才能够完成该操作,在成员函数中不行.
如果C接口库需要C++运行时支持,且要使用cc进行链接,则在使用C接口库时,还必须用libC(兼容模式)或libCrun(标准模式)链接应用程序.
(如果C接口库不需要C++运行时支持,就不必用libC或libCrun进行链接.
)归档库与共享库的链接步骤是不同的.
提供归档的C接口库时,必须提供如何使用该库的说明.
如果C接口库是在标准模式(缺省模式)下使用CC生成的,那么在使用该C接口库时,将-lCrun添加到cc命令行.
如果C接口库是在兼容模式(-compat)下使用CC生成的,那么在使用该C接口库时,将-lC添加到cc命令行.
提供共享的C接口库时,必须在生成库时创建对libC或libCrun的依赖性.
如果共享库具有正确的依赖性,就不必在使用该库时将-lC或-lCrun添加到命令行.
如果要在兼容模式(-compat)下生成C接口库,应在生成库时将-lC添加到CC命令行.
如果要在标准模式(缺省模式)下生成C接口库,应在生成库时将-lCrun添加到CC命令行.
如果要删除对C++运行时库的任何依赖性,应该在库源文件中强制应用下列代码规则:不要使用任何形式的new或delete,除非提供了自己的相应版本.
不要使用异常.
不要使用运行时类型信息(RTTI).
16.
8使用dlopen从C程序访问C++库如果要使用dlopen()从C程序打开C++共享库,应确保共享库依赖于适当的C++运行时(对于-compat=4,为libC.
so.
5;对于-compat=5,为libCrun.
so.
1).
为此,应在生成共享库时,将-lC(对于-compat=4)或lCrun(对于-compat=5)添加到命令行.
例如:16.
7生成具有CAPI的库SunStudio12:C++用户指南190example%CC-G-compat=4.
.
.
-lCexample%CC-G-compat=5.
.
.
-lCrun如果共享库使用了异常且不具有对C++运行库的依赖性,则C程序可能会出现无规律的行为.
注–使用dlopen()打开共享库时,必须使用RTLD_GLOBAL,异常才能生效.
16.
8使用dlopen从C程序访问C++库第16章生成库191192附录第4部分193194C++编译器选项本附录详细介绍了C++编译器的命令行选项.
介绍的功能适用于除了特别注明之外的所有平台;基于SPARC的系统上的Solaris操作系统特有的功能标识为SPARC,基于x86的系统上的Solaris操作系统特有的功能标识为x86.
本手册的此部分使用前言中列出的印刷约定来说明各个选项.
圆括号、大括号、方括号、"|"或"-"字符以及省略号是选项说明中使用的元字符,而不是选项自身的一部分.
A.
1选项信息的结构为了帮助您查找信息,编译器选项说明被分为以下几个子节.
如果一个选项被其他选项取代或与其他选项一致,就请参阅其他选项的说明以获取完整的详细信息.
表A–1选项子节子节内容选项定义紧跟在每个选项之后的简短定义.
(该类无标题.
)值如果选项具有一个或多个值,则本节将定义每个值.
缺省值如果选项具有主缺省值或辅助缺省值,则在此处进行声明.
如果未指定选项,则主缺省值为有效选项值.
例如,如果未指定–compat,则缺省值为–compat=5.
如果指定了选项但不给定任何值,则辅助缺省值为有效选项值.
例如,如果指定了–compat但未提供值,则缺省值为-compat=4.
扩展如果选项具有宏扩展,则将在本节中显示.
A附录A195表A–1选项子节(续)子节内容示例如果要举例说明选项,则在此处给出所需示例.
交互如果选项与其他选项进行交互,则在此处讨论它们的关系.
警告如果有对选项使用的提醒(例如可能产生不期望的行为的操作),则在此处说明.
另请参见本节包含到其他选项或文档中更多信息的引用.
"替换为"、"与.
.
.
相同"如果选项已废弃且已被其他选项替换,则在此处说明替换的选项.
以后的发行版本可能不支持这种方式描述的选项.
如果有两个选项具有相同的含义和用途,则在此处引用首选项.
例如,"与-xO相同"表示-xO是首选项.
A.
2选项参考本节按字母顺序列出所有的C++编译器选项,并指出所有的平台限制.
A.
2.
1–386x86:与–xtarget=386相同.
提供该选项只是为了向后兼容.
A.
2.
2–486x86:与–xtarget=486相同.
提供该选项只是为了向后兼容.
A.
2.
3–a与–xa相同.
A.
2.
4–Bbinding指定链接的库绑定是symbolic、dynamic(共享)还是static(非共享).
可以在命令行上多次使用–B选项.
该选项传递给链接程序ld.
A.
2选项参考SunStudio12:C++用户指南196注–在Solaris64位编译环境中,许多系统库只能用作动态库.
因此,请勿在命令行上将-Bstatic用作最后一个切换开关.
A.
2.
4.
1值binding必须是下列值之一:值含义dynamic指示链接编辑器查找liblib.
so(共享)文件,如果未找到这些文件,则查找liblib.
a(静态非共享)文件.
当链接需要共享库绑定时,请使用该选项.
static指示链接编辑器只查找liblib.
a(静态非共享)文件.
当链接需要非共享库绑定时,请使用该选项.
symbolic如果可能,则强制在共享库中解析符号(即使符号已经在别处定义).
请参见ld(1)手册页.
(–B和binding值之间不能有空格.
)缺省值如果没有指定-B,则使用–Bdynamic.
交互要静态链接C++缺省库,请使用–staticlib选项.
-Bstatic和-Bdynamic选项会影响缺省情况下提供的库的链接.
要确保动态链接缺省库,最后使用的–B应该是–Bdynamic.
在64位环境中,许多系统库只能用作共享动态库.
其中包括libm.
so和libc.
so(不提供libm.
a和libc.
a).
因此,在64位Solaris操作系统中,-Bstatic和-dn可能会导致产生链接错误.
这些情况下应用程序必须与动态库链接.
示例以下编译器命令链接libfoo.
a(即使libfoo.
so存在也是如此),所有其他库都是动态链接:example%CCa.
o–Bstatic–lfoo–BdynamicA.
2选项参考附录AC++编译器选项197警告对于包含C++代码的程序,切勿使用-Bsymbolic,而应使用链接程序映射文件.
如果使用-Bsymbolic,不同模块中的引用会绑定到应是一个全局对象内容的不同副本.
异常机制依赖对地址的比较.
如果您具有某项内容的两个副本,它们的地址就不等同且异常机制可能失败,这是由于异常机制依赖对假设为唯一地址内容的比较.
如果在不同的步骤中进行编译和链接,并要使用-Bbinding选项,就必须在链接步骤中包括该选项.
另请参见–nolib、–staticlib、ld(1)、第137页中的"12.
5静态链接标准库"和《链接程序和库指南》A.
2.
5–c仅编译;生成.
o目标文件,但抑制链接.
该选项指示CC驱动程序抑制通过ld进行链接,并为每个源文件生成一个.
o文件.
如果只在命令行上指定一个源文件,就可以用-o选项显式指定目标文件.
A.
2.
5.
1示例如果输入CC-cx.
cc,则会生成x.
o目标文件.
如果输入CC-cx.
cc-oy.
o,则会生成y.
o目标文件.
警告当编译器为输入文件(.
c、.
i)生成目标代码时,编译器总是在工作目录下生成.
o文件.
如果抑制链接步骤,则不会删除.
o文件.
另请参见–ofilename和–xeA.
2.
6–cg{89|92}与–xcg{89|92}相同.
A.
2选项参考SunStudio12:C++用户指南198A.
2.
7–compat[={4|5}]设置编译器的主要发行版兼容模式.
此选项控制__SUNPRO_CC_COMPAT和__cplusplus宏.
C++编译器有两个主要模式.
兼容模式接受4.
2编译器所定义的ARM语义和语言.
标准模式接受符合ANSI/ISO标准的构造.
由于ANSI/ISO标准在名称损坏、虚函数表布局和其他ABI详细信息中强制进行显著的不兼容的更改,所以这两个模式是互相不兼容的.
这两个模式由–compat选项进行区分,下文中介绍了相应值.
A.
2.
7.
1值-compat选项可以有下列值.
值含义–compat=4(兼容模式)设置语言和二进制使其与4.
0.
1、4.
1和4.
2编译器兼容.
将__cplusplus预处理程序宏和__SUNPRO_CC_COMPAT预处理程序宏分别设置为1和4.
–compat=5(标准模式)设置语言和二进制使其与ANSI/ISO标准模式兼容.
将__cplusplus预处理程序宏和__SUNPRO_CC_COMPAT预处理程序宏分别设置为199711L和5.
缺省值如果没有指定–compat选项,则假定–compat=5.
如果仅指定–compat,则假定–compat=4.
交互在兼容模式(-compat[=4])下,不能使用标准库.
–compat[=4]不能与下列任何选项一起使用.
-Bsymbolic-features=[no%]strictdestrorder-features=[no%]tmplife-library=[no%]iostream-library=[no%]Cstd-library=[no%]Crun-library=[no%]rwtools7_std-xarch=native64、-xarch=generic64、-xarch=v9、-xarch=v9a或-xarch=v9b–compat=5不能与下列任何选项一起使用.
-BsymbolicA.
2选项参考附录AC++编译器选项199+efeatures=[no%]arraynewfeatures=[no%]explicitfeatures=[no%]namespacefeatures=[no%]rttilibrary=[no%]complexlibrary=[no%]libC-vdelx警告生成共享库时,不要使用-Bsymbolic.
另请参见《C++迁移指南》A.
2.
8+d请勿扩展C++内联函数.
按照C++语言规则,C++内联函数是一个函数,对于该函数以下语句之一为真.
该函数的定义中使用了关键字inline该函数在类定义内部定义(不仅是声明)该函数是编译器生成的类成员函数按照C++语言规则,编译器可以选择是否将调用实际内联到内联函数.
C++编译器将调用内联到内联函数,除非:函数过于复杂已选定+d选项已选定-g选项A.
2.
8.
1示例缺省情况下,编译器可以内联以下代码示例中的函数f()和memf2().
此外,该类具有编译器可以内联的由编译器生成的缺省构造函数和析构函数.
使用+d时,编译器不会内联f()和C::mf2()(即构造函数和析构函数).
inlineintf(){return0;}//maybeinlinedclassC{intmf1();//notinlinedunlessinlinedefinitioncomeslaterintmf2(){return0;}//maybeinlined};A.
2选项参考SunStudio12:C++用户指南200交互指定了调试选项–g时,会自动启用该选项.
但指定调试选项–g0并不会启用+d.
+d选项对使用-xO4或-xO5时执行的自动内联没有影响.
另请参见–g0和–gA.
2.
9-Dname[=def]为预处理程序定义宏符号name.
使用该选项与在源文件开头包含#define指令等效.
可以使用多个-D选项.
A.
2.
9.
1值下表显示了预定义的宏.
可以在诸如#ifdef之类的预处理程序条件下使用这些值.
表A–2预定义的宏平台宏名称说明SPARC和x86__ARRAYNEW如果启用了"数组"形式的运算符new和delete,则定义__ARRAYNEW.
有关更多信息,请参见-features=[no%]arraynew.
__BUILTIN_VA_ARG_INCR适用于varargs.
h、stdarg.
h和sys/varargs.
h中的__builtin_alloca、__builtin_va_alist和__builtin_va_arg_incr关键字.
__DATE____FILE____LINE____STDC__设置为0(零)__SUNPRO_CC=0x590__SUNPRO_CC值代表编译器的发行版本号.
__SUNPRO_CC_COMPAT=4或__SUNPRO_CC_COMPAT=5请参见第199页中的"A.
2.
7–compat[={4|5}]"__TIME__A.
2选项参考附录AC++编译器选项201表A–2预定义的宏(续)平台宏名称说明__cplusplus__'uname–s'_'uname–r'其中,uname-s是uname–s的输出,uname-r是uname-r的输出,且无效字符(如句点(.
))替换为下划线,如-D__SunOS_5_9和-D__SunOS_5_10所示.
__unix_BOOL如果启用了类型bool,则定义_BOOL.
有关更多信息,请参见-features=[no%]bool.
_WCHAR_Tunix请参见交互.
SPARC__SUN_PREFETCH=1__SunOS_OSversion_OSversion__SVR4__sparc__sunsparc请参见交互.
sun请参见交互.
SPARCv9__sparcv9只限于64位编译模式x86i386linux__amd64__gnu__linux____i386请参见交互.
__linux__linux____x86_64如果不使用=def,则name定义为1.
交互如果使用+p,则不会定义sun、unix、sparc和i386.
A.
2选项参考SunStudio12:C++用户指南202另请参见–UA.
2.
10–d{y|n}允许或不允许将动态库用于整个可执行文件.
该选项传递给ld.
该选项只能在命令行出现一次.
A.
2.
10.
1值值含义-dy在链接编辑器中指定动态链接.
–dn在链接编辑器中指定静态链接.
缺省值如果没有指定-d选项,则使用–dy.
交互在64位环境中,许多系统库只能用作共享动态库.
其中包括libm.
so和libc.
so(不提供libm.
a和libc.
a).
因此,在64位Solaris操作系统中,-Bstatic和-dn可能会导致产生链接错误.
这些情况下应用程序必须与动态库链接.
警告如果将此选项与动态库结合使用,将导致致命错误.
大多数系统库仅作为动态库可用.
另请参见ld(1)和《链接程序和库指南》.
A.
2.
11–dalign-dalign与-xmemalign=8s等效.
有关更多信息,请参见第291页中的"A.
2.
144-xmemalign=ab".
A.
2选项参考附录AC++编译器选项203A.
2.
11.
1警告如果使用–dalign编译一个程序单元,就要使用-dalign编译该程序的所有单元,否则会产生意外的结果.
A.
2.
12–dryrun显示但不编译驱动程序所生成的子命令.
该选项指示驱动程序CC显示但不执行编译驱动程序构造的子命令.
A.
2.
13–E对源文件运行预处理程序,但不进行编译.
指示CC驱动程序仅对C++源文件运行预处理程序,并将结果发送到stdout(标准输出).
此时,不进行编译,且不生成.
o文件.
此选项会导致输出中包含预处理程序类型的行号信息.
A.
2.
13.
1示例该选项用于确定预处理程序所进行的更改.
例如,以下程序foo.
cc会生成第204页中的"A.
2.
13.
1示例"中所示的输出.
示例A–1预处理程序示例foo.
cc#if__cplusplusintpower(int,int);#endifintmain(){intx;x=power(2,10);}.
示例A–2使用-E选项时foo.
cc的预处理程序输出example%CC-Efoo.
cc#4"foo.
cc"templateintpower(int,int);A.
2选项参考SunStudio12:C++用户指南204示例A–2使用-E选项时foo.
cc的预处理程序输出(续)intmain(){intx;x=power(2,10);}警告使用模板时,从该选项的输出不支持作为C++编译器的输入.
另请参见–PA.
2.
14+e{0|1}在兼容模式(-compat[=4])下控制虚拟表的生成.
在标准模式下(缺省模式)无效并被忽略.
A.
2.
14.
1值+e选项可以有下列值.
值含义0禁止虚拟表的生成并创建对所需虚拟表的外部引用.
1为所有定义的具有虚函数的类创建虚拟表.
交互使用该选项进行编译时,也可以使用–features=no%except选项.
否则,编译器会为用于异常处理的内部类型生成虚拟表.
如果模板类具有虚函数,就可能无法确保编译器生成全部所需的虚拟表而不复制这些表.
另请参见《C++迁移指南》A.
2选项参考附录AC++编译器选项205A.
2.
15-erroff[=t]此命令会抑制C++编译器警告消息,但对错误消息没有影响.
此选项适用于所有警告消息,无论这些警告消息是否已被-errwarn指定为导致非零退出状态.
A.
2.
15.
1值t是一个逗号分隔列表,它包含以下项中的一项或多项:tag、no%tag、%all、%none.
顺序是很重要的;例如%all,no%tag抑制除tag以外的所有警告消息.
下表列出了-erroff值:表A–3-erroff值值含义tag抑制由该tag指定的警告消息.
可通过-errtags=yes选项来显示消息的标记.
no%tag启用由该tag指定的警告消息.
%all禁止所有警告消息.
%none启用所有警告消息(缺省).
缺省值缺省值为-erroff=%none.
指定-erroff与指定-erroff=%all等效.
示例例如,-erroff=tag将抑制由该标记指定的警告消息.
另外,-erroff=%all,no%tag将抑制除由tag指定的消息之外的所有警告消息.
可以使用-errtags=yes选项显示警告消息的标记.
警告使用-erroff选项只能抑制来自C++编译器前端且在使用-errtags选项时显示标记的警告消息.
另请参见-errtags和-errwarn.
A.
2.
16-errtags[=a]显示来自C++编译器前端且可以使用-erroff选项抑制或使用-errwarn选项使其成为致命警告的每个警告消息的消息标记.
A.
2选项参考SunStudio12:C++用户指南206A.
2.
16.
1值和缺省a可以是yes或no.
缺省值为-errtags=no.
指定-errtags与指定-errtags=yes等效.
警告来自C++编译器驱动程序和编译系统其他组件的消息没有错误标记,因此不能使用-erroff抑制,也不能使用-errwarn使其成为致命消息.
另请参见-erroff和-errwarnA.
2.
17-errwarn[=t]使用-errwarn会导致C++编译器在出现给定的警告消息时以失败状态退出.
A.
2.
17.
1值t是一个逗号分隔列表,它包含以下项中的一项或多项:tag、no%tag、%all、%none.
顺序很重要,例如如果出现除tag之外的任何警告,%all,no%tag会使cc以致命状态退出.
下表详细列出了-errwarn值:表A–4-errwarn值值含义tag如果该tag指定的消息以警告消息的形式出现,就会使CC以致命状态退出.
如果未出现tag,则没有影响.
no%tag防止CC在由tag指定的消息只以警告消息形式出现时以致命状态退出.
如果未发出tag指定的消息,则不会产生任何影响.
为了避免在发出警告消息时导致cc以致命状态退出,可使用该选项来还原以前用该选项和tag或%all指定的警告消息.
%all使CC在出现任何警告消息时以致命状态退出.
%all可以后跟no%tag,以避免该行为的特定警告消息.
%none防止CC在出现任何警告消息时以致命状态退出.
缺省值缺省值为-errwarn=%none.
如果单独指定-errwarn,它与-errwarn=%all等效.
A.
2选项参考附录AC++编译器选项207警告使用-errwarn选项只能对来自C++编译器前端且在使用了-errtags选项时会显示标记的警告消息进行指定,从而使编译器以失败状态退出.
由于编译器错误检查的改善和功能的增加,C++编译器生成的警告消息也会因发行版本而异.
使用-errwarn=%all进行编译而不会产生错误的代码,在编译器下一个发行版本中编译时也可能出现错误.
另请参见-erroff和-errtagsA.
2.
18–fast此选项是一个宏,可以有效地用作优化可执行文件的起点,从而获得最佳运行时性能.
-fast是一个宏,随编译器发行版本的升级而变化,并扩展为目标平台特定的多个选项.
可使用-#选项或-xdryrun检查-fast的扩展,并将适当的-fast选项结合到正在进行的可执行文件优化过程中.
该选项是一个宏,选择编译选项的组合用于在编译代码的机器上优化执行速度.
A.
2.
18.
1扩展该选项通过扩展到以下编译选项,为大量应用程序提供了几乎最高的性能.
表A–5-fast扩展选项SPARCx86–fnsXX–fsimple=2XX–nofstore-X-xarchXX-xbuiltin=%allXX-xdependXX–xlibmilXX–xlibmoptXX–xmemalignX-A.
2选项参考SunStudio12:C++用户指南208表A–5-fast扩展(续)选项SPARCx86–xO5XX-xregs=frameptr-X–xtarget=nativeXX交互-fast宏可扩展为可能影响其他指定选项的编译选项.
例如,在以下命令中,-fast宏的扩展包括了将-xarch还原为某个32位体系结构选项的-xtarget=native.
错误:example%CC-xarch=v9-fasttest.
cc正确:example%CC-fast-xarch=v9test.
cc查看每个选项的描述以确定可能的交互操作.
代码生成选项、优化级别、内建函数的优化和内联模板文件的使用可以用后续选项来覆盖(请参阅示例).
指定的优化级别将覆盖以前所设置的优化级别.
–fast选项包括–fns–ftrap=%none,即该选项禁用所有陷阱操作.
示例执行以下编译器命令,优化级别将为–xO3.
example%CC–fast–xO3执行以下编译器命令,优化级别将为–xO5.
example%CC-xO3–fast警告如果在不同的步骤中进行编译和链接,则编译命令和链接命令中都必须有-fast选项.
使用-fast选项编译的代码不可移植.
例如,在UltraSPARCIII系统中用以下命令生成的二进制文件在UltraSPARCII系统中无法执行.
example%CC-fasttest.
cc不要将该选项用于依赖IEEE标准浮点运算的程序,否则可能会产生不同的数字结果、过早的程序终止或意外的SIGFPE信号.
A.
2选项参考附录AC++编译器选项209在早期的SPARC发行版中,-fast宏扩展到了-fsimple=1.
而现在扩展到-fsimple=2.
在早期发行版本中,-fast宏扩展到了-xO4.
而现在扩展到了-xO5.
注–在早期的SPARC发行版中,–fast宏选项包括–fnonstd,但现在不包括.
非标准浮点模式不用–fast进行初始化.
请参见《数值计算指南》和ieee_sun(3M).
另请参见-fns、-fsimple、-ftrap=%none、-xlibmil、-nofstore、-xO5、-xlibmopt和-xtarget=nativeA.
2.
19–features=a[,a.
.
.
]启用/禁用逗号分隔的列表中指定的各种C++语言功能.
A.
2.
19.
1值在兼容模式(-compat[=4])和标准模式(缺省模式)下,a都可以具有以下值:表A–6兼容模式和标准模式下的-features值值含义%all在指定模式(兼容模式或标准模式)下有效的所有-features选项.
[no%]altspell[不]识别替换标记拼写(如"and"表示"&&").
在兼容模式下缺省值为no%altspell,在标准模式下缺省值为altspell.
[no%]anachronisms[不]允许过时的构造.
禁用时(即-features=no%anachronisms),不允许使用任何过时构造.
缺省值为anachronisms.
[no%]bool[不]允许bool类型和文字.
启用时,宏为_BOOL=1.
未启用时,不定义宏.
在兼容模式下,缺省值为no%bool,在标准模式下,缺省值为bool.
[no%]conststrings[不]将文字字符串放入只读存储器中.
在兼容模式下,缺省值为no%conststrings,在标准模式下,缺省值为conststrings.
A.
2选项参考SunStudio12:C++用户指南210表A–6兼容模式和标准模式下的-features值(续)值含义[no%]except[不]允许C++异常.
C++异常处于禁用状态时(即-features=no%except),接受但忽略函数的抛出规范,编译器不生成异常代码.
请注意,通常保留关键字try、throw和catch.
请参见第94页中的"8.
3禁用异常".
缺省值为except.
[no%]export[不]识别关键字export.
在兼容模式下,缺省值为no%export,在标准模式下,缺省值为export.
[no%]extensions[不]允许其他C++编译器通常接受的非标准代码.
有关使用-features=extensions选项时编译器接受的无效代码的说明,请参见表3–17.
缺省值为no%extensions.
[no%]iddollar[不]允许$符号作为非首字母标识符字符.
缺省值为no%iddollar.
[no%]localfor[不]对for语句使用新的局部作用域规则.
在兼容模式下,缺省值为no%localfor,在标准模式下,缺省值为localfor.
[no%]mutable[不]识别关键字mutable.
在兼容模式下,缺省值为no%mutable,在标准模式下,缺省值为mutable.
[no%]split_init[不]将非局部静态对象的初始化函数放入个别函数中.
使用-features=no%split_init时,编译器将所有初始化函数放入一个函数中.
使用-features=no%split_init可最大限度减小代码大小,但编译时间可能增加.
缺省值为split_init.
[no%]transitions[不]允许ARM语言构造,该构造会在标准C++下产生问题,且可能使程序无法按预期工作或以后可能不能编译.
使用-features=no%transitions时,编译器会将这些情况视为错误.
在标准模式下使用-features=transitions时,编译器会发出关于这些构造的警告,而不是错误消息.
在兼容模式(-compat[=4])下使用-features=transitions时,编译器仅在指定了+w或+w2的情况下才显示有关这些构造的警告.
以下构造视为转换错误:在使用了模板后再重新定义模板,遗漏模板定义中所需的typename指令,以及隐式声明类型int.
在以后的发行版本中可能会更改转换错误的集合.
缺省值为transitions.
%none关闭指定模式中可以关闭的所有功能.
在标准模式(缺省模式)下,a可以有下列其他值:表A–7仅适用于标准模式的-features值值含义[no%]strictdestrorder[不]遵循由C++标准指定的要求,该要求关于具有静态存储持续时间对象的析构顺序.
缺省值为strictdestrorder.
A.
2选项参考附录AC++编译器选项211表A–7仅适用于标准模式的-features值(续)值含义[no%]tmplrefstatic[不]允许函数模板引用相关静态函数或静态函数模板.
缺省值是遵循标准的no%tmplrefstatic.
[no%]tmplife[不]清除由位于全表达式结尾处的表达式(在ANSI/ISOC++标准中定义)创建的临时对象.
(-features=no%tmplife生效时,多数临时对象会在其块终结时清除.
)缺省值为no%tmplife.
在兼容模式(-compat[=4])下,a可以有下列其他值.
表A–8仅适用于兼容模式的-features值值含义[no%]arraynew[不]识别数组形式的运算符new和delete(如operatornew[](void*)).
启用时,宏为__ARRAYNEW=1.
未启用时,不定义宏.
缺省值为no%arraynew.
[no%]explicit[不]识别关键字explicit.
缺省值为no%explicit.
[no%]namespace[不]识别关键字namespace和using.
缺省值为no%namespace.
使用-features=namespace是为了协助将代码转换到标准模式.
通过启用该选项,将这些关键字作为标识符使用时就会出现错误消息.
关键字识别选项使您能够使用增加的关键字,而不必在标准模式下进行编译.
[no%]rtti[不]允许运行时类型信息(RTTI).
必须启用RTTI才能使用dynamic_cast和typeid运算符.
在-compat=4模式下,缺省值为no%rtti.
其他情况下,缺省值为-features=rtti,此时不允许使用选项-features=no%rtti.
注–允许使用[no%]castop设置,以便与针对C++4.
2编译器编写的makefile兼容,但对5.
0、5.
1、5.
2和5.
3版编译器没有影响.
新式强制类型转换(const_cast、dynamic_cast、reinterpret_cast和static_cast)总是可识别,不能禁用它们).
缺省值如果未指定–features,则假定:兼容模式(-compat[=4])–features=%none,anachronisms,except,split_init,transitions标准模式(缺省模式)A.
2选项参考SunStudio12:C++用户指南212–features=%all,no%iddollar,no%extensions,no%tmplife交互该选项会累积而不覆盖.
在标准模式(缺省)中以下选项与标准库和头文件不兼容:no%boolno%exceptno%mutableno%explicit在兼容模式(-compat[=4])下,-features=transitions选项不起作用,除非指定了+w选项或+w2选项.
警告指定-features=%all或-features=%none时务必谨慎.
features的设置可能会随每个编译器发行版和补丁程序而发生变化.
从而可能会有一些您不希望获得的程序行为发生.
使用-features=tmplife选项时,程序的行为可能会发生变化.
测试在使用与不使用-features=tmplife选项两种情况下程序是否正常运行是一种测试程序可移植性的方法.
在兼容模式(-compt=4)下,编译器会在缺省情况下假定-features=split_init.
如果使用-features=%none选项禁用其他功能,就会发现需要改用-features=%none,split_init重新将初始化函数分到单独的函数中.
另请参见表3–17和《C++迁移指南》.
A.
2.
20-filt[=filter[,filter.
.
.
]]控制编译器通常应用于链接程序和编译器错误消息的过滤功能.
A.
2.
20.
1值filter必须是下列值之一.
A.
2选项参考附录AC++编译器选项213表A–9-filt值值含义[no%]errors[不]显示链接程序错误消息的C++解释.
链接程序的诊断信息被直接提供到其他工具时,可以禁止这种解释.
[no%]names[不]还原C++损坏链接程序名称.
[no%]returns[不]还原函数的返回类型.
禁止该类型的还原可以使您更快速地识别函数的名称,但请注意联合变体返回的部分函数只在返回类型上有区别.
[no%]stdlib[不]在链接程序和编译器错误消息中简化标准库的名称.
这使您可更容易地识别出标准库模板类型的名称.
%all等效于-filt=errors,names,returns,stdlib.
这是缺省行为.
%none等效于-filt=no%errors,no%names,no%returns,no%stdlib.
缺省值如果未指定-filt选项或指定了-filt但未提供任何值,则编译器假定-filt=%all.
示例以下示例显示了使用-filt选项编译该代码的效果.
//filt_demo.
ccclasstype{public:virtual~type();//nodefinitionprovided};intmain(){typet;}如果编译代码时不使用-filt选项,编译器就假定-filt=errors,names,returns,stdlib并显示标准输出.
example%CCfilt_demo.
ccUndefinedfirstreferencedsymbolinfiletype::~type()filt_demo.
otype::__vtblfilt_demo.
o[Hint:trycheckingwhetherthefirstnon-inlined,non-purevirtualfunctionofclasstypeisdefined]ld:fatal:Symbolreferencingerrors.
Nooutputwrittentoa.
out以下命令禁止还原C++损坏链接程序名称,并禁止链接程序错误的C++解释.
A.
2选项参考SunStudio12:C++用户指南214example%CC-filt=no%names,no%errorsfilt_demo.
ccUndefinedfirstreferencedsymbolinfile__1cEtype2T6M_v_filt_demo.
o__1cEtypeG__vtbl_filt_demo.
old:fatal:Symbolreferencingerrors.
Nooutputwrittentoa.
out现在考虑以下代码:#include#includeintmain(){std::listl;std::strings(l);//errorhere}下面是指定了-filt=no%stdlib时的输出:Error:Cannotusestd::list>toinitializestd::basic_string,std::allocator>.
下面是指定了-filt=stdlib时的输出:Error:Cannotusestd::listtoinitializestd::string.
交互指定了no%names时,returns和no%returns都无效.
也就是说,以下选项是相同的:-filt=no%names-filt=no%names,no%returns-filt=no%names,returnsA.
2.
21–flags与–xhelp=flags相同.
A.
2.
22-fma[={none|fused}](SPARC)启用浮点乘加指令的自动生成.
-fma=none禁用这些指令的生成.
-fma=fused允许编译器通过使用浮点乘加指令,尝试寻找改进代码性能的机会.
缺省值是-fma=none.
A.
2选项参考附录AC++编译器选项215要使编译器生成乘加指令,最低要求是-xarch=sparcfmaf且优先级别至少为-xO2.
如果生成了乘加指令,编译器会标记此二进制程序,以防止该程序在不受支持的平台上执行.
A.
2.
23–fnonstd使硬件自陷可用于浮点溢出,除以零,并可用于无效运算异常.
产生的结果被转换为SIGFPE信号,如果程序没有SIGFPE处理程序,它就会终止并转储内存(除非将核心转储大小限制到零).
SPARC:此外,-fnonstd还选择SPARC非标准浮点.
A.
2.
23.
1缺省值如果未指定–fnonstd,则IEEE754浮点算术异常不会中止程序,而是出现逐渐下溢情况.
扩展x86:-fnonstd扩展到-ftrap=common.
SPARC:-fnonstd扩展到-fnsftrap=common.
另请参见–fns、–ftrap=common和《数值计算指南》.
A.
2.
24–fns[={yes|no}]SPARC:启用/禁用SPARC的非标准浮点模式.
如果使用-fns=yes(或-fns),则会在程序开始执行时启用非标准浮点模式.
该选项提供了一种切换使用非标准浮点模式或标准浮点模式的方法,它接在包括–fns的其他某些宏选项(如–fast)后面.
在某些SPARC设备上,非标准浮点模式会禁用"逐渐下溢",这会导致很小的结果刷新为零而不是生成次正规数,还会导致次正规数操作数被默置为零.
对于那些硬件中不支持逐渐下溢和次正规数的SPARC设备,-fns=yes(或-fns)可以显著提高某些程序的性能.
(x86)选择SSE刷新为零模式以及(如果可用)非正规数为零模式.
此选项导致将次正规结果刷新为零.
如果可用的话,此选项还导致将次正规操作数视为零.
此选项不会影响利用SSE或SSE2指令集的传统x86浮点运算.
A.
2选项参考SunStudio12:C++用户指南216A.
2.
24.
1值-fns选项可以有下列值.
表A–10-fns值值含义yes选择非标准浮点模式no选择标准浮点模式缺省值如果未指定-fns,则不自动启用非标准浮点模式.
进行标准IEEE754浮点计算(即逐渐下溢).
如果仅指定了–fns,则假定–fns=yes.
示例在以下示例中,-fast扩展为多个选项,其中一个是-fns=yes,即选择非标准浮点模式.
后续-fns=no选项覆盖初始设置,并选择浮点模式.
example%CCfoo.
cc-fast-fns=no警告非标准模式启动时,浮点运算可以产生不符合IEEE754标准要求的结果.
如果使用-fns选项编译一个例程,就要使用–fns选项编译该程序的所有例程,否则就会产生意外的结果.
该选项仅在SPARC设备上有效,并且仅在编译主程序时才能有效使用.
在x86设备上,此选项被忽略.
使用–fns=yes(或-fns)选项时,如果程序中出现通常由IEEE浮点陷阱处理程序管理的浮点错误,则会出现以下消息:另请参见《数值计算指南》和ieee_sun(3M).
A.
2.
25–fprecision=px86:设置非缺省浮点精度模式.
A.
2选项参考附录AC++编译器选项217–fprecision选项用于设置浮点控制字中的舍入精度模式位.
这些位控制基本算术运算(加、减、乘、除和平方根)结果的舍入精度.
A.
2.
25.
1值p必须是下列值之一.
表A–11-fprecision值值含义single舍入到IEEE单精度值.
double舍入到IEEE双精度值.
extended舍入到最大可用精度.
如果p为single或double,则该选项会使舍入精度模式在程序开始执行时分别设置为single或double精度.
如果p是extended或未使用–fprecision,则舍入精度模式保持为extended精度.
在single精度舍入模式下,结果将舍入到24个有效位;在double精度舍入模式下,结果将舍入到53个有效位.
在缺省的extended精度模式下,结果将舍入到64个有效位.
该模式只控制在寄存器中结果的舍入精度,而不影响范围.
寄存器中所有的结果都使用了各种已扩展的双精度格式来舍入.
不过,存储在内存中的结果既舍入到目标格式的范围也舍入到目标格式的精度.
float类型的标称精度为single.
longdouble类型的标称精度为extended.
缺省值如果未指定–fprecision选项,舍入精度模式缺省为extended.
警告此选项仅对x86设备且仅在编译主程序时使用才有效.
在SPARC设备上,该选项被忽略.
A.
2.
26–fround=r启动时设置有效的IEEE舍入模式.
该选项将IEEE754舍入模式设置为:编译器可以将其用于计算常量表达式程序初始化期间在运行时建立A.
2选项参考SunStudio12:C++用户指南218含义与ieee_flags子例程的含义相同,可用于更改运行时的模式.
A.
2.
26.
1值r必须是下列值之一.
表A–12-fround值值含义nearest舍入到最接近的数字并转变为偶数.
tozero舍入到零.
negative舍入到负无穷大.
positive舍入到正无穷大.
缺省值如果未指定–fround选项,舍入模式缺省为-fround=nearest.
警告如果使用–fround=r编译一个例程,就要使用相同的–fround=r选项编译该程序的所有例程,否则就会产生意外的结果.
只有编译主程序时该选项才有效.
A.
2.
27–fsimple[=n]选择浮点优化首选项.
该选项允许优化器简化关于浮点运算的假定.
A.
2.
27.
1值如果存在n,它必须是0、1或2.
表A–13-fsimple值值含义0不允许简化假定.
保持严格的IEEE754一致性.
A.
2选项参考附录AC++编译器选项219表A–13-fsimple值(续)值含义1允许保守简化.
产生的代码与IEEE754不完全一致,但多数程序所产生的数值结果没有改变.
在-fsimple=1的情况下,优化器可假定:进程初始化之后,不更改IEEE754的缺省舍入/自陷模式.
除产生潜在浮点异常的计算不能删除外,产生不可视结果的计算都可以删除.
使用无穷大或NaNs作为操作数的计算需要将NaNs传送到它们的结果中,即x*0可以用零替换.
计算不依赖于零的符号.
在-fsimple=1的情况下,不允许优化器不考虑舍入或异常进行完全优化.
具体来讲,运行时将舍入模式保存为常量时,不能用产生不同结果的计算来替换浮点计算.
2包括-fsimple=1的所有功能,还允许可能导致许多程序生成不同的数值结果(由于舍入的更改)的主动浮点优化.
例如,允许优化器在指定循环中使用x*z来替换所有x/y运算,其中,要保证在循环z=1/y中至少对x/y求一次值,并且在执行该循环期间已知y和z的值为常量值.
缺省值如果未指定–fsimple,编译器将使用-fsimple=0.
如果指定了-fsimple但未指定n值,编译器将使用-fsimple=1.
交互-fast隐含了–fsimple=2.
警告该选项可以破坏IEEE754的一致性.
另请参见-fastRajatGarg和IlyaSharapov合著的《TechniquesforOptimizingApplications:HighPerformanceComputing》,该书详细介绍了优化对精度的影响.
A.
2选项参考SunStudio12:C++用户指南220A.
2.
28–fstorex86:强制浮点表达式的精度.
在以下值为真时,该选项使编译器将浮点表达式或函数的值转换为赋值左侧的类型,而不是将该值保留在寄存器中:将表达式或函数分配到变量.
表达式被强制转换为较短的浮点类型.
要禁用此选项,请使用–nofstore选项.
A.
2.
28.
1警告由于误差和截断,结果可能会与寄存器值所生成的结果不同.
另请参见–nofstoreA.
2.
29–ftrap=t[,t.
.
.
]设置启动时生效的IEEE陷阱操作模式,但不安装SIGFPE处理程序.
可以使用ieee_handler(3M)或fex_set_handling(3M)启用陷阱并同时安装SIGFPE处理程序.
如果指定多个值,则按从左到右顺序处理列表.
A.
2.
29.
1值t可以是下列值之一.
表A–14-ftrap值值含义[no%]division[不]在除以零时自陷.
[no%]inexact[不]在结果不精确时自陷.
[no%]invalid[不]在无效操作上自陷.
[no%]overflow[不]在溢出上自陷.
[no%]underflow[不]在下溢上自陷.
%all在所有以上内容中自陷.
A.
2选项参考附录AC++编译器选项221表A–14-ftrap值(续)值含义%none不在以上任何内容中自陷.
common在无效、除以零和溢出时自陷.
注意,选项的[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)手册页.
A.
2.
30–G生成动态共享库而不是可执行文件.
缺省情况下,在命令行上指定的所有资源文件都是使用-xcode=pic13进行编译的.
生成使用模板的共享库时,多数情况下有必要将这些模板函数包括在共享库中,而这些函数已在模板数据库中实例化.
使用该选项可以将这些模板自动增加到所需的共享库中.
如果要通过指定-G与其他必须在编译时和链接时指定的编译器选项来创建共享对象,请确保在编译时和与生成的共享对象链接时也指定这些选项.
A.
2选项参考SunStudio12:C++用户指南222创建共享对象时,所有使用-xarch=v9编译的目标文件也必须使用第269页中的"A.
2.
116–xcode=a"中推荐的显式-xcode值进行编译.
A.
2.
30.
1交互如果未指定–c(仅编译选项),以下选项将传递给链接程序:–dy–G–R警告请勿使用ld-G生成共享库,而应使用CC-G.
CC驱动程序会自动将C++所需的多个选项传递给ld.
使用-G选项时,编译器不将任何缺省-l选项传递到ld选项.
如果您要使共享库具有对另一共享库的依赖性,就必须在命令行上传递必需的-l选项.
例如,如果要使共享库依赖于libCrun,必须在命令行上传递-lCrun.
另请参见-dy、-Kpic、-xcode=pic13、–ztext、ld(1)手册页,以及第188页中的"16.
3生成动态(共享)库".
A.
2.
31–g生成附加的符号表信息,以供使用dbx(1)或调试器进行调试以及使用性能分析器analyzer(1)进行分析.
指示编译器和链接程序准备进行调试和性能分析的文件或程序.
其任务包括:生成以目标文件和可执行文件的符号表形式表示的详细信息(称为stabs).
生成某些"帮助应用程序函数",调试器可以调用这些函数来实现其某些功能.
禁用函数的内联生成.
禁用优化的某些级别.
A.
2.
31.
1交互如果将此选项与–xOlevel(或其等价选项,如-O)一起使用,将会获得一些特定的调试信息.
有关更多信息,请参见第295页中的"A.
2.
150-xOlevel".
如果使用该选项且优化级别为-xO4或更高,编译器会为完全优化提供尽可能多的符号信息.
A.
2选项参考附录AC++编译器选项223指定了该选项时,会自动指定+d选项.
注–在以前的发行版中,此选项强制编译器在缺省情况下使用增量链接程序(ild),而不使用用于编译器的仅链接调用的链接程序(ld).
也就是说,在使用-g的情况下,编译器的缺省行为是每当使用编译器链接目标文件时就自动调用ild而不是ld,除非在命令行上指定了-G或源文件.
现在已不再是这种情况.
增量链接程序不再可用.
要使用性能分析器的完整功能,请使用-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的详细信息)和《程序性能分析工具》.
A.
2.
32–g0编译和链接以便进行调试,但不禁用内联.
此选项与–g相同,但+d处于禁用状态,dbx无法步入内联函数.
如果指定-g0且优化级别为-xO3或更低,编译器会为近乎完全优化提供尽可能多的符号信息.
尾部调用优化和后端内联被禁用.
A.
2.
32.
1另请参见+d、–g和《使用dbx调试程序》.
A.
2.
33–H打印所包含文件的路径名.
A.
2选项参考SunStudio12:C++用户指南224在标准错误输出(stderr)中,该选项打印当前编译中包含的每个#include文件的路径名(每行一个).
A.
2.
34–h[]name为生成的动态共享库指定名称name.
这是一个加载器选项,传递给ld.
通常,-h后面的名称应该与–o后面的名称完全相同.
–h和name之间的空格是可选的.
编译时的加载器将指定名称分配到正在创建的共享动态库中,并将该名称作为库的内部名称记录在库文件中.
如果没有–hname选项,则没有内部名称记录在库文件中.
每个可执行文件都具有所需的共享库文件列表.
当运行时链接程序将库链接到可执行文件中时,链接程序将内部名称从库复制到所需共享库文件的列表中.
如果没有共享文件的内部名称,链接程序就复制共享库文件的路径.
A.
2.
34.
1示例example%CC-G-olibx.
so.
1-hlibx.
so.
1a.
ob.
oc.
oA.
2.
35–help与-xhelp=flags相同.
A.
2.
36-Ipathname将pathname添加到#include文件中的搜索路径中.
该选项用于将pathname添加到在其中搜索具有相对文件名(不以斜杠开头的文件名)的#include文件的目录列表.
编译器按以下顺序搜索用引号引住的文件(形式为#include"foo.
h").
1.
在包含源代码的目录中2.
在使用-I选项指定的目录(如果有)中3.
在编译器提供的C++头文件、ANSIC头文件和专用文件的include目录中4.
在/usr/include目录中编译器按以下顺序搜索用尖括号括住的文件(形式为#include).
1.
在使用-I选项指定的目录(如果有)中2.
在编译器提供的C++头文件、ANSIC头文件和专用文件的include目录中3.
在/usr/include目录中A.
2选项参考附录AC++编译器选项225注–如果此拼写与标准头文件的名称匹配,另请参阅第140页中的"12.
7.
5标准头文件实现".
A.
2.
36.
1交互-I-选项让您可以覆盖缺省的搜索规则.
如果指定了-library=no%Cstd,那么编译器在其搜索路径中就不包括编译器提供的与C++标准库关联的头文件.
请参见第138页中的"12.
7替换C++标准库".
如果未使用–ptipath,编译器就会在–Ipathname中查找模板文件.
请使用–Ipathname而不是–ptipath.
该选项会累积而不覆盖.
警告任何时候都不要将编译器安装区域/usr/include、/lib或/usr/lib指定为搜索目录.
另请参见-I-A.
2.
37-I-将头文件的搜索规则更改为:对于形式为#include"foo.
h"的include文件,按以下顺序搜索目录.
对于形式为#include"foo.
h"的include文件,按以下顺序搜索目录:1.
使用-I选项指定的目录(在-I-前后).
2.
编译器提供的C++头文件、ANSIC头文件和专用文件的目录.
3.
/usr/include目录.
对于#include形式的include文件,按以下顺序搜索目录:1.
使用-I选项指定的目录(在-I-后面).
2.
编译器提供的C++头文件、ANSIC头文件和专用文件的目录.
3.
/usr/include目录.
A.
2选项参考SunStudio12:C++用户指南226注–如果包括文件的名称与标准头的名称相匹配,另请参阅第140页中的"12.
7.
5标准头文件实现".
A.
2.
37.
1示例以下示例显示了编译prog.
cc时使用-I-的结果.
prog.
cc#include"a.
h"#include#include"c.
h"c.
h#ifndef_C_H_1#define_C_H_1intc1;#endifinc/a.
h#ifndef_A_H#define_A_H#include"c.
h"inta;#endifinc/b.
h#ifndef_B_H#define_B_H#includeintb;#endifinc/c.
h#ifndef_C_H_2#define_C_H_2intc2;#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-Hprog.
ccinc/a.
hinc/c.
hinc/b.
hinc/c.
hc.
hA.
2选项参考附录AC++编译器选项227以下命令显示了-I-选项的效果.
编译器处理形式为#include"foo.
h"的语句时,并不先在包含目录中查找,而是按照通过-I选项指定的目录在命令行上的显示顺序搜索这些目录.
在inc/a.
h中处理#include"c.
h"语句时,编译器将.
/c.
h头文件而不是inc/c.
h头文件包含进来.
example%CC-c-I.
-I--Iinc-Hprog.
ccinc/a.
h.
/c.
hinc/b.
hinc/c.
h.
/c.
h交互命令行上有-I-时,编译器从不搜索当前目录,除非在-I指令中显式列出了该目录.
甚至是形式为#include"foo.
h"的包含语句,也是这种情况.
警告只有命令行上的第一个-I-会导致出现所述行为.
任何时候都不要将编译器安装区域/usr/include、/lib或/usr/lib指定为搜索目录.
A.
2.
38–i通知链接程序ld忽略任何LD_LIBRARY_PATH设置.
A.
2.
39-inline与-xinline相同.
A.
2.
40–instances=a控制模板实例的放置和链接.
A.
2.
40.
1值a必须是下列值之一.
A.
2选项参考SunStudio12:C++用户指南228表A–15-instances值值含义extern将全部所需示例放置到comdat部分的模块系统信息库并赋予全局链接.
(如果系统信息库中的实例过期,就会被重新实例化.
)注意:如果在不同的步骤中进行编译和链接,并且在编译步骤中指定了-instance=extern,则还必须在链接步骤中指定该选项.
explicit将显式实例化的实例放置到当前目标文件中并赋予全局链接.
不生成其他任何所需实例.
global将全部所需的实例放置到当前目标文件中并赋予全局链接.
semiexplicit将显式实例化的实例放置到当前目标文件中并赋予全局链接.
将显式实例所需的全部实例放置到当前目标文件中并赋予全局链接.
不生成其他任何所需实例.
static注意:-instances=static已过时.
没有任何理由再使用-instances=static,因为-instances=global现在提供了静态的所有优点而没有其缺点.
以前编译器中提供的该选项用于克服此编译器版本中不存在的问题.
将全部所需的实例放置到当前目标文件中并赋予静态链接.
缺省值如果未指定–instances,则假定–instances=global.
另请参见第86页中的"7.
2.
4模板实例的放置和链接".
A.
2.
41–instlib=filename使用该选项可避免在库(共享或静态)和当前对象中生成重复的模板实例.
一般来说,如果程序与库共享大量实例,可以尝试使用-instlib=filename,看看编译时间是否会减少.
A.
2.
41.
1值:可使用filename参数指定已知包含现有模块实例的库.
filename参数必须包含正斜杠"/"字符.
对于相对于当前目录的路径,请使用点斜杠".
/".
缺省:-instlib=filename选项没有缺省值,只有在指定后才能使用.
该选项可被多次指定和累积.
A.
2选项参考附录AC++编译器选项229示例:假定libfoo.
a和libbar.
so库可对与源文件a.
cc共享的大量模板实例进行实例化.
添加-instlib=filename并指定库可通过避免冗余有利于减少编译时间.
example%CC-c-instlib=.
/libfoo.
a-instlib=.
/libbar.
soa.
cc交互:使用-g进行编译时,如果使用-instlib=file指定的库没有使用-g编译,那么这些模板实例不可调试.
解决方法是避免在使用-g时使用-instlib=file.
警告如果使用-instlib指定库,就必须与该库链接.
另请参见:-template、-instances和-ptiA.
2.
42–KPICSPARC:与–xcode=pic32相同.
x86:与–Kpic相同.
生成共享库时使用该选项编译源文件.
对全局数据的每个引用都生成为全局偏移表中指针的非关联化.
每个函数调用都通过过程链接表在pc相对地址模式中生成.
A.
2.
43–KpicSPARC:与–xcode=pic13相同.
x86:使用与位置无关的代码进行编译.
生成共享库时使用该选项编译源文件.
对全局数据的每个引用都生成为全局偏移表中指针的非关联化.
每个函数调用都通过过程链接表在pc相对地址模式中生成.
A.
2.
44–keeptmp保留编译时创建的临时文件.
该选项与–verbose=diags一起使用,对调试很有用.
A.
2选项参考SunStudio12:C++用户指南230A.
2.
44.
1另请参见–v,–verboseA.
2.
45–Lpath将path添加到要在其中搜索库的目录列表.
该选项传递给ld.
搜索顺序是先搜索通过path指定的目录,再搜索编译器提供的目录.
A.
2.
45.
1交互该选项会累积而不覆盖.
警告任何时候都不要将编译器安装区域/usr/include、/lib或/usr/lib指定为搜索目录.
A.
2.
46–llib将库liblib.
a或liblib.
so添加到链接程序的搜索库列表.
该选项传递给ld.
常规库的名称如liblib.
a或liblib.
so,其中,lib和.
a或.
so这些部分是必需的.
应该使用此选项指定lib部分.
应在一个命令行上输入尽可能多的库,对这些库搜索时按照使用–Ldir指定的顺序进行.
请在目标文件名之后使用该选项.
A.
2.
46.
1交互该选项会累积而不覆盖.
较稳妥的方式是总是将–lx放在源文件和目标文件列表后面,这样可以确保按正确顺序搜索库.
警告为了确保正确的库链接顺序,必须使用-mt(而不是-lthread)与libthread链接.
另请参见–Ldir、-mt、第124页中的"11.
4.
8示例应用程序"和《Tools.
h++类库参考》A.
2选项参考附录AC++编译器选项231A.
2.
47–libmieee与–xlibmieee相同.
A.
2.
48–libmil与-xlibmil相同.
A.
2.
49-library=l[,l.
.
.
]将指定的CC提供的库加入编译和链接操作中.
A.
2.
49.
1值对于兼容模式(–compat[-4]]),l必须是下列值之一.
表A–16适用于兼容模式的-library值值含义[no%]f77已过时.
改用-xlang=f77.
[no%]f90已过时.
改用-xlang=f90.
[no%]f95已过时.
改用-xlang=f95.
[no%]rwtools7[不]使用传统iostreamTools.
h++版本[no%]rwtools7_dbg[不]使用支持调试的Tools.
h++版本7.
[no%]complex[不]将libcomplex用于复数算术运算.
[no%]interval已过时.
不要使用.
使用-xia.
[no%]libC[不]使用C++支持库libC.
[no%]gc[不]使用垃圾收集libgc.
[no%]sunperf[不]使用SunPerformanceLibraryTM.
%none仅使用C++库libC.
在标准模式(缺省模式)下,l必须是下列值之一:A.
2选项参考SunStudio12:C++用户指南232表A–17适用于标准模式的-library值值含义[no%]f77已过时.
改用-xlang=f77.
[no%]f90已过时.
改用-xlang=f90.
[no%]f95已过时.
改用-xlang=f95.
[no%]rwtools7[不]使用传统iostreamTools.
h++版本[no%]rwtools7_dbg[不]使用支持调试的Tools.
h++版本7.
[no%]rwtools7_std[不]使用传统iostreamTools.
h++版本[no%]rwtools7_std_dbg[不]使用支持调试的标准iostreamTools.
h++版本[no%]interval已过时.
不要使用.
使用-xia.
[no%]iostream[不]使用传统iostream库libiostream.
[no%]Cstd[不]使用C++标准库libCstd.
[不]包括编译器提供的C++标准库头文件.
[no%]Crun[不]使用C++运行时库libCrun.
[no%]gc[不]使用垃圾收集libgc.
[no%]stlport4[不]使用STLport的标准库实现版本4.
5.
3来代替缺省的libCstd.
关于使用STLport实现的更多信息,请参阅第156页中的"13.
3STLport".
[no%]stlport4_dbg[不]使用STLport的支持调试的库.
[no%]sunperf[不]使用SunPerformanceLibrary.
%none仅使用C++库libCrun.
缺省值兼容模式(–compat[=4])如果未指定–library,则假定-library=libC.
libC库总是包括在内,除非使用-library=no%libC明确将其排除.
标准模式(缺省模式)libCstd库总是包括在内,除非使用-library=%none、-library=no%Cstd或-library=stlport4明确将其排除.
libCrun库总是包括在内.
无论是标准模式还是兼容模式,libm和libc库总是包括在内,即使指定了-library=%none也是如此.
A.
2选项参考附录AC++编译器选项233示例要在标准模式下没有任何C++库(除libCrun之外)时进行链接,请使用:example%CC-library=%none要在标准模式下将传统iostreamRoguetools.
h++库包含进来,请使用:example%CC–library=rwtools7,iostream要在标准模式下将标准iostreamRogueWavetools.
h++库包含进来,请使用:example%CC-library=rwtools7_std要在兼容模式下将传统iostreamRogueWavetools.
h++库包含进来,请使用:example%CC-compat-library=rwtools7交互如果使用-library指定了库,则在编译期间会设置适当的–I路径.
在链接期间会设置适当的–L、–YP、–R路径和–l选项.
该选项会累积而不覆盖.
在使用区间运算库时,必须包括以下库之一:libC、libCstd或libiostream.
使用-library选项可确保针对指定库的-l选项按正确顺序传送.
例如,对于-library=rwtools7,iostream和-library=iostream,rwtools7,-l选项都是按照-lrwtool-liostream顺序传递给ld.
指定的库在系统支持库链接之前链接.
不能在同一个命令行上使用-library=sunperf和-xlic_lib=sunperf.
不能在同一个命令行上使用-library=stlport4和-library=Cstd.
每次只能使用一个RogueWave工具库,而且不能将任何RogueWave工具库与-library=stlport4一起使用.
在标准模式(缺省模式)下包含传统iostreamRogueWave工具库时,必须也要包含libiostream(有关其他信息,请参见《C++迁移指南》.
只能在标准模式下使用标准iostreamRogueWave工具库.
以下命令示例显示了有效使用和无效使用RogueWavetools.
h++库选项的情况.
%CC-compat-library=rwtools7foo.
cc#includeintmain()A.
2选项参考附录AC++编译器选项247{std::coutstructS{voidimf(){}staticvoidsmf(){}};templateclassS;intmain(){}example%指定了-template=geninlinefuncs时,即使在程序中没有调用S的两个成员函数,也会在目标文件中生成它们.
example%CC-c-template=geninlinefuncsExample.
ccexample%nm-CExample.
oExample.
o:[Index]ValueSizeTypeBindOtherShndxName[5]00NOTYGLOB0ABS__fsr_init_value[1]00FILELOCL0ABSb.
c[4]1632FUNCGLOB02main[3]10424FUNCLOCL02voidS::imf()[__1cBS4Ci_Dimf6M_v_][2]6420FUNCLOCL02voidS::smf()[__1cBS4Ci_Dsmf6F_v_]另请参见第85页中的"7.
2.
2整个类实例化"和第90页中的"7.
5模板定义搜索"A.
2选项参考附录AC++编译器选项249A.
2.
93–time与–xtime相同.
A.
2.
94–Uname删除预处理程序符号name的初始定义.
该选项会删除在命令行上通过-D(包括CC驱动程序隐式放在命令行上的选项)创建的宏符号name的所有初始定义.
该选项对任何其他预定义的宏和源文件中的宏定义都没有影响.
要查看CC驱动程序放在命令行上的-D选项,请将-dryrun选项添加到命令行上.
A.
2.
94.
1示例以下命令取消预定义符号__sun的定义.
foo.
cc中的预处理程序语句(例如#ifdef(__sun))会知道该符号已取消定义.
example%CC-U__sunfoo.
cc交互可以在命令行上指定多个-U选项.
所有-U选项都在出现的任何-D选项之后处理.
也就是说,如果在命令行上为-D和-U指定了相同的name,则name是未定义的,而不管这些选项出现的顺序如何.
另请参见-DA.
2.
95–unroll=n与–xunroll=n相同.
A.
2.
96–V与–verbose=version相同.
A.
2.
97–v与–verbose=diags相同.
A.
2选项参考SunStudio12:C++用户指南250A.
2.
98–vdelx已过时,不使用.
仅限于兼容模式(–compat[=4]):对于使用delete[]的表达式,该选项生成对运行时库函数_vector_deletex_的调用,而不是生成对_vector_delete_的调用.
函数_vector_delete_使用两个参数:要删除的指针以及每个数组元素的大小.
函数_vector_deletex_的行为与_vector_delete_的行为相同,但前者使用第三个参数:类的析构函数的地址.
第三个参数不用于该函数,而是供第三方供应商使用.
A.
2.
98.
1缺省对于使用delete[]的表达式,编译器生成对_vector_delete_的调用.
警告这是在以后的发行版本中要删除的废弃选项.
除非您已从第三方供应商购买了某些软件且供应商推荐使用该选项,否则请不要使用该选项.
A.
2.
99–verbose=v[,v…]控制编译器详细程度.
A.
2.
99.
1值v必须是下列值之一.
表A–22-verbose值值含义[no%]diags[不]为每个编译传递打印命令行.
[no%]template[不]打开模板实例verbose模式(有时称为"检验"模式).
verbose模式显示编译过程中出现的每个实例阶段.
[no%]version[不]指示CC驱动程序打印所调用程序的名称和版本号.
%all调用以上所有内容.
%none-verbose=%none与-verbose=no%template,no%diags,no%version相同.
缺省值如果未指定–verbose,则假定–verbose=%none.
A.
2选项参考附录AC++编译器选项251交互该选项会累积而不覆盖.
A.
2.
100+w识别出可能会产生意外后果的代码.
使用+w选项时,如果函数过大而无法内联或未使用声明的程序元素,就不再生成警告.
这些警告不指定源代码中的真正问题,因此不适合某些开发环境.
从+w中删除这些警告就可以在这些环境下更主动地使用+w.
在+w2选项中仍可以使用这些警告.
该选项生成如下关于有问题构造的其他警告:不可移植可能出错低效A.
2.
100.
1缺省值如果未指定+w,则编译器发出有关极可能是问题的构造的警告.
交互某些C++标准头文件会导致在使用+w编译时出现警告.
另请参见–w和+w2.
A.
2.
101+w2发出+w发出的所有警告以及可能无害但可能降低程序最大可移植性的技术违规的警告.
+w2选项不再发出关于在系统头文件中使用与实现相关的构造方面的警告.
因为系统头文件是实现,所以发出警告是不合适的.
从+w2删除这些警告可以更主动地使用该选项.
A.
2.
101.
1警告某些SolarisOS和C++标准头文件会导致在使用+w2编译时出现警告.
另请参见+wA.
2选项参考SunStudio12:C++用户指南252A.
2.
102–w抑制大部分警告消息.
该选项使编译器不打印警告消息.
但不能抑制某些警告(尤其是有关严重记时错误的警告).
A.
2.
102.
1另请参见+wA.
2.
103–Xm与–features=iddollar相同.
A.
2.
104–xa为文件配置生成代码.
如果在编译时设置,则由环境变量TCOVDIR指定覆盖(.
d)文件所在的目录.
如果未设置该变量,则覆盖(.
d)文件仍与source文件保存在同一目录中.
使用该选项是为了向后兼容旧的覆盖文件.
A.
2.
104.
1交互-xprofile=tcov和-xa选项在单个可执行程序中兼容.
也就是说,在您链接的同一个程序中,既可包含用–xprofile=tcov编译的一些文件,又可包含用–xa编译的另外一些文件.
不能同时用这两个选项来编译同一文件.
–xa选项与–g不兼容.
警告如果在不同的步骤中进行编译和链接,且使用-xa进行编译,应确保使用–xa进行链接,否则会产生意外的结果.
另请参见–xprofile=tcov、tcov(1)手册页和《程序性能分析工具》.
A.
2选项参考附录AC++编译器选项253A.
2.
105-xalias_level[=n](SPARC)指定了以下命令时,C++编译器可以执行基于类型的别名分析和优化:-xalias_level[=n]其中n是any、simple或compatible.
-xalias_level=any在此分析级别上,编译器假定任何类型都可以为其他类型起别名.
不过尽管只是假定,但还是可以执行某些优化.
-xalias_level=simple编译器假定简单的类型没有别名.
具体来说就是具有动态类型的存储对象,这些类型是以下简单类型之一:charshortintlongintfloatsignedcharunsignedshortintunsignedlongintdoubleunsignedcharintlonglongintlongdoublewchar_tunsignedintunsignedlonglongint枚举类型数据指针类型函数指针类型数据成员指针类型函数成员指针类型只能通过以下类型的左值访问:对象的动态类型动态类型对象的constant或volatile限定版本,与动态类型对象对应的带符号或无符号类型与动态类型对象的constant或volatile限定版本对应的带符号或无符号类型在其成员(包括递归的子集成员或包含的联合)中包括上述类型的聚集或联合类型char或unsignedchar类型-xalias_level=compatible编译器假定布局不兼容类型没有别名.
存储对象只能通过以下类型的左值访问:对象的动态类型对象动态类型的constant或volatile限定版本,与对象动态类型相对应的带符号或不带符号的类型与动态类型对象的constant或volatile限定版本对应的带符号或无符号类型在其成员(包括递归的子集成员或包含的联合)中包括上述类型的聚集或联合类型A.
2选项参考SunStudio12:C++用户指南254动态类型对象的(可能是constant或volatile限定)基类类型char或unsignedchartype.
编译器假定所有引用的类型都与相应存储对象的动态类型是布局兼容的.
两种类型在以下情况下是布局兼容的:如果两个类型相同,则这两个类型就是布局兼容的类型.
如果两个类型仅在constant或volatile限定中不同,则这两个函数是布局兼容的类型.
每个存在的带符号整型对应(但是不相同)一个无符号整型.
这些对应的类型是布局兼容的.
如果两个枚举类型具有相同的基础类型,则它们是布局兼容的.
如果两个简单旧数据(PlainOldData,POD)结构类型具有相同数量的成员,并且对应的成员(按顺序)具有布局兼容的类型,那么这两个结构类型是布局兼容的.
如果两个POD联合类型具有相同数量的成员,并且对应的成员(按顺序)具有布局兼容的类型,那么这两个联合类型是布局兼容的.
在某些情况下具有存储对象动态类型的引用可能是非布局兼容的:如果POD联合包含了两个或两个以上共享通用初始序列的POD结构,且POD联合对象当前包含了其中一个POD结构,就可以检查任何POD结构的通用初始部分.
对包含一个或多个初始成员的序列来说,如果相应成员具有布局兼容类型(适用于位字段)和相同宽度,则两个POD结构共享一个通用初始序列.
指向POD结构对象的指针(使用reinterpret_cast适当转换)将指向该结构的初始成员,而如果该成员是位字段则指向该结构所在的单元.
A.
2.
105.
1缺省值如果未指定-xalias_level,则编译器将该选项设置为-xalias_level=any.
如果指定了-xalias_level但未提供值,则编译器将该选项设置为-xalias_level=compatible.
交互编译器在-xO2和更低的优化级别不执行基于类型的别名分析.
警告如果要使用reinterpret_cast或等价的旧式强制类型转换,程序可能会违反分析假定.
此外,联合类型也违反了分析的假定,如以下示例所示.
unionbitbucket{inti;floatf;};A.
2选项参考附录AC++编译器选项255intbitsof(floatf){bitbucketvar;var.
f=3.
6;returnvar.
i;}A.
2.
106–xar创建归档库.
生成使用模板的C++归档文件时,多数情况下有必要将这些模板函数包括在该归档文件中.
这些函数已在模板数据库中被实例化.
使用该选项可以将这些模板自动增加到所需的归档文件中.
A.
2.
106.
1值对调用ar-c-r指定-xar并重新创建归档文件.
示例以下命令行归档包含在库和目标文件中的模板函数.
example%CC-xar-olibmain.
aa.
ob.
oc.
o警告请勿在命令行上添加来自模板数据库中的.
o文件.
请勿直接使用ar命令生成归档文件.
应使用CC–xar以确保模板实例自动包括在归档文件中.
另请参见ar(1)和表15–3A.
2.
107–xarch=isa指定目标指令集体系结构(instructionsetarchitecture,ISA).
该选项将编译器生成的代码限制为特定指令集体系结构的指令.
该选项不保证使用任何目标特定的指令.
不过,使用该选项会影响二进制程序的可移植性.
A.
2选项参考SunStudio12:C++用户指南256注–分别使用-m64或-m32选项来指定打算使用的内存模型LP64(64位)或ILP32(32位).
-xarch选项不再指示内存模型,除非是为了与早期的发行版兼容,如下所示.
A.
2.
107.
1用于SPARC的-xarch标志下表提供了SPARC平台上每个-xarch关键字的详细信息.
表A–23用于SPARC平台的-xarch标志标志含义generic使用大多数处理器通用的指令集.
这是缺省设置.
generic64为了在大多数64位平台上获得良好性能而进行编译.
(仅限Solaris).
此选项与-m64-xarch=generic等效,用于与早期发行版兼容.
使用-m64而非-xarch=generic64来指定64位编译.
native为了在此系统上获得良好性能而进行编译.
编译器为运行它的当前系统处理器选择适当的设置.
native64编译以在此系统中取得良好的性能(仅限Solaris).
此选项等效于-m64-xarch=native,用于与早期的发行版兼容.
sparc针对SPARC-V9ISA(但不带有可视化指令集(VisualInstructionSet,VIS),也不带有其他特定于实现的ISA扩展)进行编译.
该选项在V9ISA上使编译器生成高性能代码.
sparcvis针对具有可视化指令集(VisualInstructionSet,VIS)版本1.
0和UltraSPARC扩展的SPARC-V9进行编译.
该选项在UltraSPARC体系结构上使编译器生成高性能代码.
sparcvis2此选项允许编译器为具有UltraSPARCIII扩展和可视化指令集(VisualInstructionSet,VIS)2.
0版的UltraSPARC体系结构生成目标代码.
sparcfmaf使该编译器可以使用SPARC-V9指令集中的指令、UltraSPARC扩展(包括可视化指令集(VisualInstructionSet,VIS)版本1.
0),UltraSPARC-III扩展(包括可视化指令集(VisualInstructionSet,VIS)版本2.
0)以及SPARC64VI扩展来进行浮点乘加.
必须将-xarch=sparcfmaf与fma=fused结合使用,并具有某个优化级别,以使编译器尝试查找机会来自动使用乘加指令.
v7针对SPARC-V7ISA进行编译.
(已废弃)当前的Solaris操作系统不再支持SPARCV7体系结构,并且使用此选项编译的程序在当前平台上的运行速度较慢.
缺省值为-xarch=v8plus.
示例:SPARCstation1,SPARCstation2.
A.
2选项参考附录AC++编译器选项257表A–23用于SPARC平台的-xarch标志(续)标志含义v8a针对SPARC-V8ISA的V8a版本进行编译.
按照定义,V8a是指不包含fsmuld指令的V8ISA.
该选项使编译器能够生成可在V8aISA上获得良好性能的代码.
示例:基于microSPARCI芯片架构的任何系统v8针对SPARC-V8ISA进行编译.
使编译器能够生成用于在V8架构上获得良好性能的代码.
示例:SPARCstation10v8plus针对SPARC-V9ISA的V8plus版本进行编译.
根据定义,V8plus是指V9ISA,但只限于由V8plusISA规范所定义的32位子集,而不包括可视化指令集(VisualInstructionSet,VIS)和其他特定实现的ISA扩展.
该选项使编译器能够生成可在V8plusISA上获得良好性能的代码.
生成的目标代码采用SPARC-V8+ELF32格式,只能在SolarisUltraSPARC环境下执行(不能在V7和V8处理器上运行).
示例:基于UltraSPARC芯片体系结构的任何系统v8plusa针对SPARC-V9ISA的V8plusa版本进行编译.
根据定义,V8plusa是指V8plus体系结构加可视化指令集(VisualInstructionSet,VIS)版本1.
0和UltraSPARC扩展.
该选项使编译器能够生成可在UltraSPARC体系结构上获得良好性能的代码,但只限于V8plus规范定义的32位子集.
生成的目标代码采用SPARC-V8+ELF32格式,只能在SolarisUltraSPARC环境下执行(不能在V8处理器上运行).
示例:基于UltraSPARC芯片体系结构的任何系统v8plusb针对具有UltraSPARCIII扩展的SPARC-V8plusISA的V8plusb版本进行编译.
此选项允许编译器为具有UltraSPARCIII扩展和可视化指令集(VisualInstructionSet,VIS)2.
0版的UltraSPARC体系结构生成目标代码.
生成的目标代码采用SPARC-V8+ELF32格式,只能在SolarisUltraSPARC-III环境中执行.
使用此选项进行编译将使用最佳指令集,以便在UltraSPARCIII体系结构上获得良好性能.
v9等效于-m64-xarch=sparc.
使用-xarch=v9来获取64位内存模型的传统makefile和脚本仅需使用-m64.
v9a等效于-m64-xarch=sparcvis,用于与早期发行版兼容.
v9b等效于-m64-xarch=sparcvis2,用于与早期发行版兼容.
另请注意:SPARC指令集体系结构V8和V8a均是二进制兼容的.
A.
2选项参考SunStudio12:C++用户指南258可以一起链接和执行使用v8plus和v8plusa编译的二进制目标文件(.
o),但只能在SPARCV8plusa兼容平台上运行.
可以一起链接和执行使用v8plus、v8plusa和v8plusb编译的二进制目标文件(.
o),但只能在SPARCV8plusb兼容平台上运行.
-xarch值v9、v9a和v9b只能在UltraSPARC64位Solaris操作系统中使用.
可以一起链接和执行使用generic64、native64、v9和v9a编译的二进制目标文件(.
o),但只能在SPARCV9a兼容平台上运行.
可以一起链接和执行使用generic64、native64、v9、v9a和v9b编译的二进制目标文件(.
o),但只能在SPARCV9b兼容平台上运行.
对于任何特定选择,生成的可执行文件在早期体系结构中运行时都会慢得多.
此外,虽然在多数指令集体系结构中都可以使用四精度(REAL*16和longdouble)浮点指令,但编译器不在它生成的代码中使用这些指令.
用于x86的-xarch标志下表列出了x86平台上的-xarch标志.
表A–24x86上的-xarch标志标志含义386使指令集限制于386/486体系结构.
amd64等效于-m64-xarch=sse2(仅限Solaris).
使用-xarch=amd64来获取64位内存模型的传统makefile和脚本仅需要使用-m64.
amd64a等效于-m64-xarch=sse2a(仅限Solaris).
generic使用大多数处理器通用的指令集.
这是缺省设置.
generic64为了在大多数64位平台上获得良好性能而进行编译.
(仅限Solaris).
该选项等效于-m64-xarch=generic,用于与早期的发行版兼容.
使用-m64而不是-xarch=generic64来指定64位编译.
native为了在此系统上获得良好性能而进行编译.
编译器为运行它的当前系统处理器选择适当的设置.
native64编译以在此系统中取得良好的性能(仅限Solaris).
该选项等效于-m64-xarch=native,用于与早期的发行版兼容.
pentium_pro使指令集限于32位pentium_pro体系结构.
pentium_proa将AMD扩展(3DNow!
、3DNow!
扩展和MMX扩展)添加到32位pentium_pro体系结构中.
A.
2选项参考附录AC++编译器选项259表A–24x86上的-xarch标志(续)标志含义sse将SSE指令集添加到pentium_pro体系结构.
ssea将AMD扩展(3DNow!
、3DNow!
扩展和MMX扩展)添加到32位SSE体系结构中.
sse2将SSE2指令集添加到pentium_pro体系结构.
sse2a将AMD扩展(3DNow!
、3DNow!
扩展和MMX扩展)添加到32位SSE2体系结构中.
sse3将SSE3指令集添加到SSE2指令集中.
x86特别说明以下是针对x86Solaris平台进行编译时应了解的一些重要问题.
传统的Sun样式并行程序在x86上不可用.
请改用OpenMP.
有关将传统并行指令转换为OpenMP的信息,请参见《SunStudio12:OpenMPAPIUser'sGuide》.
以-xarch设置为sse、sse2、sse2a或sse3编译的程序必须在提供这些扩展和功能上的平台上运行.
从Solaris94/04开始的操作系统发行版在Pentium4兼容的平台上支持SSE/SSE2.
早期版本的Solaris操作系统不支持SSE/SSE2.
如果运行的Solaris操作系统未启用由-xarch选择的指令集,则编译器将无法为该指令集生成或链接代码.
如果在单独的步骤中编译和链接,请始终使用编译器以及相同的-xarch设置进行链接,以确保链接正确的启动例程.
x86上的数值结果可能与SPARC上的结果不同,这是由x8680位浮点寄存器造成的.
要最大限度地减少这些差异,请使用-fstore选项,或者使用-xarch=sse2进行编译(如果硬件支持SSE2的话).
Solaris和Linux的数值结果也可能不同,因为内在的数学库(如sin(x))并不相同.
二进制兼容验证从SunStudio11和Solaris10操作系统开始,会对使用这些专用的-xarch硬件标志编译和生成的程序二进制文件进行验证,看其是否在适当的平台上运行.
在Solaris10之前的系统中,不执行任何验证,用户负责确保使用这些标志生成的对象部署在合适的硬件上.
如果在没有相应功能或指令集扩展的平台上运行使用这些-xarch选项编译的程序,则可能会导致段故障或不正确的结果,并且不显示任何显式警告消息.
这一警告也扩展到使用.
il内联汇编语言功能或使用SSE、SSE2、SSE2a和SSE3指令和扩展的__asm()汇编程序代码.
A.
2选项参考SunStudio12:C++用户指南260SPARC缺省设置目前,C++编译器针对其生成代码的缺省体系结构是v8plus(UltraSPARC).
以后的发行版中将不再支持v7.
新的缺省设置几乎可为当前使用的所有计算机都产生更高的运行时性能.
但是,在缺省情况下,设计用于在UltraSPARC之前的计算机上进行部署的应用程序将不再在那些计算机上执行.
使用-xarch=v8编译可以确保这些应用程序在那些计算机上执行.
如果要在v8系统上部署,则必须在每个编译器命令行以及任何链接时命令中显式指定选项-xarch=v8.
提供的系统库将在v8体系结构上运行.
如果要在v7系统上部署,则必须在每个编译器命令行以及任何链接时命令上显式指定选项-xarch=v7.
提供的系统库将使用v8指令集.
对于此发行版,唯一支持v7的操作系统是Solaris8操作系统发行版.
遇到v8指令时,Solaris8操作系统会在软件中解释指令.
程序会运行,但性能将下降.
x86缺省设置对于x86,-xarch缺省值为generic.
请注意,x86上的-fast扩展为-xarch=native.
该选项将编译器生成的代码限制为特定指令集体系结构的指令.
该选项不保证使用任何目标特定的指令.
不过,使用该选项会影响二进制程序的可移植性.
如果在不同的步骤中编译和链接,请确保在两个步骤中为-xarch指定了相同的值.
交互尽管可以单独使用该选项,但它属于-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=v8plusbfoo.
cc不支持–compat[=4]与-xarch=generic64、-xarch=native64、-xarch=v9、-xarch=v9a或-xarch=v9b结合使用.
警告如果在进行优化时使用该选项,那么在指定体系结构上适当选择就可以提供高性能的可执行文件.
但如果选择不当就会导致性能的严重降级,或导致在预定目标平台上无法执行二进制程序.
如果在不同的步骤中编译和链接,请确保在两个步骤中为-xarch指定了相同的值.
A.
2选项参考附录AC++编译器选项261A.
2.
108-xautopar注–此选项不接受OpenMP并行化指令.
Sun特定的MPpragma已过时,并且不再受支持.
有关标准的指令的迁移信息,请参见《SunStudio12:OpenMPAPIUser'sGuide》.
(SPARC)为多个处理器启用自动并行化,执行依赖性分析(对循环进行迭代间数据依赖性分析)和循环重构.
如果优化级别不是-xO3或更高级别,则将优化级别提高到-xO3并发出警告.
如果要进行自己的线程管理,请勿使用-xautopar.
为了使执行速度更快,该选项要求使用多处理器系统.
在单处理器系统中,生成的二进制文件的运行速度通常较慢.
要在多线程环境中运行已并行化的程序,必须在执行之前设置OMP_NUM_THREADS环境变量.
有关更多信息,请参见《SunStudio12:OpenMPAPIUser'sGuide》.
如果使用-xautopar且在一个步骤中进行编译和链接,则链接会自动将微任务化库和线程安全的C运行时库包含进来.
如果使用-xautopar并在不同的步骤中进行编译和链接,则还必须使用-xautopar链接.
A.
2.
108.
1另请参见第298页中的"A.
2.
151-xopenmp[=i]"A.
2.
109-xbinopt={prepare|off}(SPARC)指示编译器准备二进制文件,以便以后进行优化、转换和分析,请参见binopt(1).
此选项可用于生成可执行文件或共享对象.
如果在不同的步骤中进行编译,则在编译步骤和链接步骤中都必须有-xbinopt:example%cc-c-xO1-xbinopt=preparea.
cb.
cexample%cc-omyprog-xbinopt=preparea.
o如果有些源代码不可用于编译,仍可使用此选项来编译其余代码.
然后,应将其用于可创建最终库的链接步骤中.
在此情况下,只有用此选项编译的代码才能进行优化、转换或分析.
A.
2.
109.
1缺省值缺省值为-xbinopt=off.
A.
2选项参考SunStudio12:C++用户指南262交互此选项必须与-xO1或更高的优化级别一起使用时才有效.
使用此选项生成二进制文件时,文件大小会有所增加.
使用-xbinopt=prepare和-g编译会将调试信息包括在内,从而增加可执行文件的大小.
A.
2.
110-xbuiltin[={%all|%none}]启用或禁用对标准库调用进行优化改进.
缺省情况下,编译器会将标准库头文件中声明的函数视为普通函数.
但编译器会将其中一些函数识别为"内函数"或"内置函数".
视为内置函数时,编译器可以生成更有效的代码.
例如,编译器可以识别无副作用的函数,且通常为给定的相同输入返回相同的输出.
编译器可将部分函数直接生成为内联函数.
有关如何读取目标文件中的编译器注解来确定编译器实际对哪些函数进行替换的说明,请参见er_src(1)手册页.
-xbuiltin=%all选项表示要求编译器识别尽可能多的内置标准函数.
所识别函数的确切列表在不同的编译器代码生成器版本中各不相同.
-xbuiltin=%none选项表示采用缺省编译器行为,编译器对内置函数不进行任何特殊优化.
A.
2.
110.
1缺省值如果未指定-xbuiltin选项,则编译器假定-xbuiltin=%none.
如果仅指定了-xbuiltin,则编译器假定-xbuiltin=%all.
交互宏-fast的扩展包括了-xbuiltin=%all.
示例下面的编译器命令请求标准库调用的特殊处理.
example%CC-xbuiltin-cfoo.
cc下面的编译器命令请求不对标准库调用进行特别处理.
请注意,宏-fast的扩展包括了-xbuiltin=%all.
example%CC-fast-xbuiltin=%none-cfoo.
ccA.
2选项参考附录AC++编译器选项263A.
2.
111–xcache=c定义要由优化器使用的高速缓存属性.
此选项不保证使用每个特定的缓存属性.
注–尽管可单独使用该选项,但它是-xtarget选项的扩展的一部分,主要用途是覆盖-xtarget选项提供的值.
此发行版引入一个可选属性[/ti],该属性用来设置可以共享缓存的线程数.
A.
2.
111.
1值c必须是下列值之一.
表A–25-xcache值值含义generic这是缺省值,该值指示编译器使用能达到以下效果的缓存属性:多数x86和SPARC处理器上都能获得良好性能,同时任何处理器性能都不会明显下降.
如果需要,在每个新的发行版本中都会调整最佳定时属性.
native设置在主机环境中最佳性能的参数.
s1/l1/a1[/t1]定义级别1缓存属性s1/l1/a1[/t1]:s2/l2/a2[/t2]定义级别1和2缓存属性s1/l1/a1[/t1]:s2/l2/a2[/t2]:s3/l3/a3[/t3]定义级别1、2和3缓存属性高速缓存属性si/li/ai/ti的定义如下:属性定义si级别为i的数据高速缓存的大小(KB)li级别为i的数据高速缓存的行大小,以字节为单位ai级别为i的数据高速缓存的关联性例如,i=1指定级别1高速缓存属性s1/l1/a1.
A.
2选项参考SunStudio12:C++用户指南264缺省值如果未指定–xcache,则假定为缺省值–xcache=generic.
该值指示了编译器在多数SPARC处理器上使用缓存属性来获得高性能,而不降低任何处理器的性能.
如果没有为t指定值,则缺省值为1.
示例–xcache=16/32/4:1024/32/1指定以下内容:级别1高速缓存具有级别2高速缓存具有16KB1024KB32字节行大小32字节行大小4方向关联指示映射关联另请参见–xtarget=tA.
2.
112-xcg[89|92](SPARC)已废弃,请勿使用此选项.
当前的Solaris操作系统软件不再支持SPARCV7体系结构.
使用此选项编译生成的代码在当前的SPARC平台中运行较慢.
应改用-O,并利用-xarch、-xchip和-xcache编译器缺省值.
A.
2.
113-xchar[=o]提供此选项只是为了方便从char类型定义为unsigned的系统中迁移代码.
如果不是从这样的系统中迁移,最好不要使用该选项.
只有那些依赖字符类型符号的程序才需要重写,它们要改写成显式指定带符号或者无符号.
A.
2.
113.
1值o可以是下列值之一:A.
2选项参考附录AC++编译器选项265表A–26-xchar值值含义signed将声明为字符的字符常量和变量视为带符号的.
这会影响已编译代码的行为,而不影响库例程的行为.
s与signed等效.
unsigned将声明为字符的字符常量和变量视为无符号的.
这会影响已编译代码的行为,而不影响库例程的行为.
u与unsigned等效.
缺省值如果未指定-xchar,编译器将假定-xchar=s.
如果指定了-xchar但未指定值,编译器将假定-xchar=s.
交互-xchar选项会更改用-xchar编译的代码中类型char的值范围.
该选项不更改任何系统例程或头文件中类型char的值范围.
具体来讲,指定选项时不更改limits.
h定义的CHAR_MAX和CHAR_MIN的值.
因此,CHAR_MAX和CHAR_MIN不再表示无格式字符中可编码的值的范围.
警告如果使用-xchar,则在将字符与预定义的系统宏进行比较时要特别小心,原因是宏中的值可能带符号.
任何返回错误代码而且可以用宏来访问错误代码的例程通常是这样的.
错误代码一般是负值,因此在将字符与此类宏中的值进行比较时,结果始终为假.
负数永远不等于无符号类型的值.
强烈建议不要使用-xchar为通过库导出的任何接口编译例程.
SolarisABI将类型char指定为带符号,并且系统库也按此指定.
还未对系统库针对将char指定为无符号的效果进行广泛测试.
可以不使用该选项,而修改您的代码使其不依赖于类型char是否带符号.
类型char的符号因不同的编译器和操作系统而不同.
A.
2.
114-xcheck[=i]SPARC:使用-xcheck=stkovf进行编译将增加对单线程程序中的主线程以及多线程程序中的从属线程栈进行栈溢出运行时检查.
如果检测到栈溢出,则生成SIGSEGV.
如果您的应用程序需要以不同于处理其他地址空间违规的方式处理栈溢出导致的SIGSEGV,请参见sigaltstack(2).
A.
2选项参考SunStudio12:C++用户指南266A.
2.
114.
1值i必须是下列值之一:表A–27-xcheck值值含义%all执行全部检查.
%none不执行检查.
stkovf打开栈溢出检查.
no%stkovf关闭栈溢出检查.
缺省值如果未指定-xcheck,则编译器缺省使用-xcheck=%none.
如果指定了没有任何参数的-xcheck,则编译器缺省使用-xcheck=%none.
在命令行上-xcheck选项不进行累积.
编译器按照上次出现的命令设置标志.
A.
2.
115-xchip=c指定要由优化器使用的目标处理器.
–xchip选项通过指定目标处理器来指定定时属性.
该选项会影响:指令的顺序(即调度)编译器使用分支的方法语义上等价的其他指令可用时使用的指令注–尽管可单独使用该选项,但它是-xtarget选项的扩展的一部分,主要用途是覆盖-xtarget选项提供的值.
A.
2.
115.
1值c必须是下列值之一.
A.
2选项参考附录AC++编译器选项267表A–28-xchip值平台值使用定时属性优化SPARCgeneric可以在多数SPARC处理器上获得高性能native可以在运行编译器的系统上获得高性能old早于SuperSPARC处理器的处理器sparc64viSPARC64VI处理器superSuperSPARC处理器super2SuperSPARCII处理器micromicroSPARC处理器micro2microSPARCII处理器hyperhyperSPARC处理器hyper2hyperSPARCII处理器powerupWeitekPowerUp处理器ultraUltraSPARC处理器ultra2UltraSPARCII处理器ultra2eUltraSPARCIIe处理器ultra2iUltraSPARCIIi处理器ultra3UltraSPARCIII处理器ultra3cuUltraSPARCIIICu处理器ultra3iUltraSparcIIIi处理器ultra4UltraSPARCIV处理器ultra4plusUltraSPARCIVplus处理器ultraT1UltraSPARCT1处理器ultraT2UltraSPARCT2处理器.
x86generic多数x86处理器386Intel386处理器486Intel486处理器pentiumIntelPentium处理器A.
2选项参考SunStudio12:C++用户指南268表A–28-xchip值(续)平台值使用定时属性优化pentium_proIntelPentiumPro处理器pentium3IntelPentium3处理器pentium4IntelPentium4处理器缺省值在大多数SPARC处理器中,generic为缺省值,即指示编译器使用最佳定时属性以获得高性能,而不会显著降低任何处理器的性能.
A.
2.
116–xcode=aSPARC:指定代码地址空间.
注–应通过指定-xcode=pic13或-xcode=pic32生成共享对象.
也可以使用-xarch=v9、-xcode=abs64和-xarch=v8、-xcode=abs32生成可用共享对象,但它们效率很低.
用-xarch=v9、-xcode=abs32或-xarch=v9、-xcode=abs44生成的共享对象无法使用.
A.
2.
116.
1值a必须是下列值之一.
表A–29-xcode值值含义abs32生成快速但有范围限制的32位绝对地址.
代码+数据+bss的大小被限制为2**32字节.
abs44SPARC:生成具有适当速度和范围的44位绝对地址.
代码+数据+bss的大小不应超过2**44字节.
只适用于64位架构:请勿将该值与动态(共享)库一起使用.
abs64SPARC:生成缓慢但无范围限制的64位绝对地址.
只适用于64位架构.
pic13生成快速但有范围限制的位置无关代码(小模型).
等效于–Kpic.
允许在32位架构上最多引用2**11个唯一的外部符号,而在64位架构上可以最多引用2**10个.
pic32生成缓慢但无范围限制的位置无关代码(大模型).
等效于–KPIC.
允许在32位体系结构上最多引用2**30个唯一的外部符号,而在64位体系结构上最多可以引用2**29个.
A.
2选项参考附录AC++编译器选项269要确定使用–xcode=pic13还是–xcode=pic32,请使用elfdump-c(有关更多信息,请参见elfdump(1)手册页)检查全局偏移表(GlobalOffsetTable,GOT)的大小;并使用sh_name:.
got检查节标题.
sh_size值是GOT的大小.
如果GOT小于8,192字节,请指定-xcode=pic13,否则请指定-xcode=pic32.
通常,应根据以下准则来确定如何使用-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命令:%nmfile.
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.
A.
2选项参考SunStudio12:C++用户指南270警告在不同的步骤中进行编译和链接时,在编译步骤和链接步骤中都必须使用相同的-xarch选项.
A.
2.
117-xcrossfile[=n]SPARC:启用跨源文件优化和内联.
-xcrossfile在编译时执行,且仅涉及编译命令中出现的文件.
请参考下列命令行示例:example%CC-xcrossfile-xO4-cf1.
ccf2.
ccexample%CC-xcrossfile-xO4-cf3.
ccf4.
cc可以在文件f1.
cc和f2.
cc之间以及f3.
cc和f4.
cc之间进行跨模块优化.
在f1.
cc和f3.
cc或f4.
cc之间不进行优化.
A.
2.
117.
1值n必须是下列值之一.
表A–30-xcrossfile值值含义0不执行跨文件优化或跨文件内联.
1执行多个源文件之间的优化和内联处理.
通常,在命令行上编译器的分析范围限于每个独立的文件.
例如,传递-xO4选项时,只对同一源文件中定义和引用的子程序进行自动内联.
使用-xcrossfile或-xcrossfile=1时,编译器会分析命令行上指定的所有文件,就好像这些文件已串联为一个源文件.
缺省值如果未指定-xcrossfile,则假定-xcrossfile=0且不执行跨文件优化和内联.
-xcrossfile与-xcrossfile=1相同.
交互-xcrossfile选项只有与-xO4或-xO5一起使用时才有效.
A.
2选项参考附录AC++编译器选项271警告这种编译所产生的文件由于可能的内联而相互依赖,而且在将这些文件链接到程序时必须将其作为一个整体使用.
如果更改了任何一个例程并重新编译了文件,则必须重新编译所有的文件.
因此,使用该选项会影响makefile的结构.
另请参见-xldscopeA.
2.
118-xdebugformat=[stabs|dwarf]编译器将调试器信息格式从stabs格式迁移为"DWARF调试信息格式"中指定的dwarf格式.
在此发行版中,缺省设置为-xdebugformat=stabs.
如果要维护读取调试信息的软件,您现在可以选择将工具从stabs格式转换为dwarf格式.
出于移植工具的目的,可以通过此选项来使用新的格式.
除非您要维护读取调试器信息的软件,或者特定工具要求使用这些格式之一的调试器信息,否则不需要使用此选项.
表A–31-xdebugformat标志值含义stabs-xdebugformat=stabs生成使用stabs标准格式的调试信息.
dwarf-xdebugformat=dwarf生成的调试信息采用dwarf标准格式.
如果未指定-xdebugformat,编译器将假定-xdebugformat=stabs.
此选项需要一个参数.
此选项会影响使用-g选项记录的数据的格式.
即使在没有使用-g的情况下记录少量调试信息,此选项仍可控制其信息格式.
因此,即使不使用-g,-xdebugformat仍有影响.
dbx和性能分析器软件可识别stabs和dwarf格式,因此使用此选项对任何工具的功能都没有影响.
注–这是过渡性接口,因此会在发行版之间发生更改而不兼容,即使在发行版更新较少时也是如此.
stabs或dwarf格式的任何特定字段或值的详细资料也在不断改进.
有关更多信息,另请参见dumpstabs(1)和dwarfdump(1)手册页.
A.
2选项参考SunStudio12:C++用户指南272A.
2.
119-xdepend=[yes|no](SPARC)分析循环以了解迭代间的数据依赖性,并进行循环重构.
循环重构包括循环交换、循环合并、标量替换和"死"数组赋值消除.
如果优化级别不是-xO3或更高级别,编译器会将优化级别提高到-xO3并发出警告.
如果未指定-xdepend,缺省设置将为-xdepend=no,该设置表示编译器不分析循环以了解数据依赖性.
如果指定-xdepend但未指定参数,编译器会将此选项设置为-xdepend=yes,该设置表示编译器分析循环以了解数据依赖性.
依赖性分析在单处理器系统中可能很有用.
但是,如果在单处理器系统中尝试使用-xdepend,则不应使用-xautopar.
如果-xautopar处于打开状态,则会为多处理器系统进行-xdepend优化.
A.
2.
120-xdumpmacros[=value[,value.
.
.
]]要查看宏在程序中的行为方式时使用此选项.
该选项提供了诸如宏定义、取消定义的宏和宏用法实例的信息,并按宏的处理顺序将输出打印到标准错误(stderr).
-xdumpmacros选项在整个文件中或在dumpmacros或end_dumpmacrospragma覆盖它之前都是有效的.
请参见第337页中的"B.
2.
5#pragmadumpmacros".
A.
2.
120.
1值value可以是下列参数:表A–32-xdumpmacros值值含义[no%]defs[不]打印所有宏定义[no%]undefs[不]打印所有宏取消定义[no%]use[不]打印关于所用宏的信息[no%]loc[不]打印defs、undefs和use的位置(路径名和行号)[no%]conds[不]打印在条件指令中宏的使用信息[no%]sys[不]打印系统头文件中所有宏的定义、取消定义的宏和宏的使用信息%all设置该选项即表示-xdumpmacros=defs,undefs,use,loc,conds,sys.
该参数最好与[no%]形式的其他参数配合使用.
例如,-xdumpmacros=%all,no%sys表示输出中不包含系统头文件宏,但仍提供所有其他宏的信息.
%none不打印任何宏信息A.
2选项参考附录AC++编译器选项273这些选项值会累积,因此指定-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%catt.
c#ifdefFOO#undefFOO#defineCOMPUTE(a,b)a+b#else#defineCOMPUTE(a,b)a-b#endifintn=COMPUTE(5,2);intj=COMPUTE(7,1);#ifCOMPUTE(8,3)+NN+MMintk=0;#endif以下示例显示了使用defs、undefs、sys和loc参数时文件t.
c的输出.
example%CC-c-xdumpmacros-DFOOt.
c#define__SunOS_5_91#define__SUNPRO_CC0x590#defineunix1#definesun1#definesparc1#define__sparc1#define__unix1#define__sun1#define__BUILTIN_VA_ARG_INCR1#define__SVR41A.
2选项参考SunStudio12:C++用户指南274#define__SUNPRO_CC_COMPAT5#define__SUN_PREFETCH1#defineFOO1#undefFOO#defineCOMPUTE(a,b)a+bexample%CC-c-xdumpmacros=defs,undefs,loc-DFOO-UBARt.
ccommandline:#define__SunOS_5_91commandline:#define__SUNPRO_CC0x590commandline:#defineunix1commandline:#definesun1commandline:#definesparc1commandline:#define__sparc1commandline:#define__unix1commandline:#define__sun1commandline:#define__BUILTIN_VA_ARG_INCR1commandline:#define__SVR41commandline:#define__SUNPRO_CC_COMPAT5commandline:#define__SUN_PREFETCH1commandline:#defineFOO1commandline:#undefBARt.
c,line2:#undefFOOt.
c,line3:#defineCOMPUTE(a,b)a+b以下示例说明了use、loc和conds参数如何报告文件t.
c中宏的行为:example%CC-c-xdumpmacros=uset.
cusedmacroCOMPUTEexample%CC-c-xdumpmacros=use,loct.
ct.
c,line7:usedmacroCOMPUTEt.
c,line8:usedmacroCOMPUTEexample%CC-c-xdumpmacros=use,condst.
cusedmacroFOOusedmacroCOMPUTEusedmacroNNusedmacroMMexample%CC-c-xdumpmacros=use,conds,loct.
ct.
c,line1:usedmacroFOOt.
c,line7:usedmacroCOMPUTEt.
c,line8:usedmacroCOMPUTEt.
c,line9:usedmacroCOMPUTEt.
c,line9:usedmacroNNt.
c,line9:usedmacroMM例如文件y.
c:A.
2选项参考附录AC++编译器选项275example%caty.
c#defineX1#defineYX#defineZYinta=Z;以下是使用-xdumpmacros=use,loc时有关y.
c中宏的输出:example%CC-c-xdumpmacros=use,locy.
cy.
c,line4:usedmacroZy.
c,line4:usedmacroYy.
c,line4:usedmacroX另请参见要覆盖-xdumpmacros的作用域时,请使用dumpmacrospragma和end_dumpmacrospragma.
A.
2.
121-xe仅检查语法和语义错误.
指定-xe时,编译器不生成任何目标代码.
-xe的输出定向到stderr.
如果不需要通过编译生成目标文件,可使用-xe选项.
例如,如果要尝试通过删除代码段找出导致出现错误消息的原因,可使用-xe加速编辑和编译周期.
A.
2.
121.
1另请参见–cA.
2.
122-xF[=v[,v.
.
.
]]启用通过链接程序对函数和变量进行最佳重新排列.
该选项指示编译器将函数和/或数据变量放置到单独的分段中,这使链接程序(使用链接程序的-M选项指定的映射文件中的指示)将这些段重新排序以优化程序性能.
通常,该优化仅在缺页时间构成程序运行时间的一大部分时才有效.
对变量重新排序有助于解决对运行时性能产生负面影响的以下问题:在内存中存放位置很近的无关变量会造成缓存和页的争用.
在内存中存放位置很远的相关变量会造成不必要的过大工作集.
未用到的弱变量副本会造成不必要的过大工作集,从而降低有效数据密度.
为优化性能而对变量和函数进行重新排序时,需要执行以下操作:A.
2选项参考SunStudio12:C++用户指南2761.
使用-xF进行编译和链接.
2.
按照《程序性能分析工具》手册中有关如何生成用于函数的映射文件的说明进行操作,或按照《链接程序和库指南》中有关如何生成用于数据的映射文件的说明进行操作.
3.
使用通过链接程序的-M选项生成的新映射文件重新链接.
4.
在分析器下重新执行以验证是否增强.
A.
2.
122.
1值v可以是下列其中一个或多个值:表A–33-xF值值含义[no%]func[不]将函数分段到单独的段中.
[no%]gbldata[不]将全局数据(具有外部链接的变量)分段到单独的段中.
[no%]lcldata[不]将局部数据(具有内部链接的变量)分段到单独的段中.
%all分段函数、全局数据和局部数据.
%none不分段.
缺省值如果未指定-xF,则缺省值为-xF=%none.
如果指定了没有任何参数的-xF,则缺省值为-xF=%none,func.
交互使用-xF=lcldata会限制某些地址计算优化,因此,只应在必要时才使用该标志.
另请参见analyzer(1)、debugger(1)和ld(1)手册页A.
2.
123–xhelp=flags显示了对每个编译器选项的简要描述.
A.
2.
124–xhelp=readme显示联机readme文件的内容.
A.
2选项参考附录AC++编译器选项277readme文件按环境变量PAGER中指定的命令分页.
如果未设置PAGER,则缺省的分页命令为more.
A.
2.
125-xhwcprof(SPARC)使编译器支持基于硬件计数器的文件配置.
如果启用了-xhwcprof,编译器将生成信息,这些信息可帮助工具将文件配置的加载和存储指令与其所引用的数据类型和结构成员相关联(与由-g生成的符号信息一起).
它将配置文件数据与目标数据空间(而非指令空间)相关联,并可以观察仅通过指令剖析不易观察的行为.
可使用-xhwcprof编译一组指定的目标文件.
但是,-xhwcprof在应用于应用程序中的所有目标文件时,作用最大.
它能全面识别并关联分布在应用程序目标文件中的所有内存引用.
如果分别在单独的步骤中进行编译和链接,最好在链接时使用-xhwcprof.
如果将来扩展为-xhwcprof,则在链接时可能需要使用它.
-xhwcprof=enable或-xhwcprof=disable的实例将会覆盖同一命令行中-xhwcprof的所有以前的实例.
在缺省情况下,禁用-xhwcprof.
指定不带任何参数的-xhwcprof与-xhwcprof=enable等效.
-xhwcprof要求启用优化并将调试数据的格式设置为DWARF(-xdebugformat=dwarf).
-xhwcprof和-g的组合会增加编译器临时文件的存储需求,而且比单独指定-xhwcprof和-g所引起的增加总量还多.
下列命令可编译example.
cc,并可为硬件计数器文件配置以及针对使用DWARF符号的数据类型和结构成员的符号分析指定支持:example%CC-c-O-xhwcprof-g-xdebugformat=dwarfexample.
cc有关基于硬件计数器的文件配置的更多信息,请参见《程序性能分析工具》手册.
A.
2.
126-xiaSPARC:链接适当的区间运算库,并设置适当的浮点环境.
注–C++区间运算库与Fortran编译器中实现的区间运算相兼容.
A.
2选项参考SunStudio12:C++用户指南278A.
2.
126.
1扩展-xia选项是一个扩展到-fsimple=0-ftrap=%none-fns=no-library=interval的宏.
如果使用区间并通过为-fsimple、-ftrap、-fns或-library指定不同的标志来覆盖-xia设置的内容,则可能会导致编译器出现不正确的行为.
交互要使用区间运算库,请将包含进来.
在使用区间运算库时,必须包括以下库之一:libC、Cstd或iostream.
有关包括这些库的信息,请参见-library.
警告如果您使用区间并为-fsimple、-ftrap或-fns指定了不同的值,则您的程序可能有不正确的行为.
C++区间运算处于实验阶段且正在改进.
不同的发行版本具有不同的功能.
另请参见《C++IntervalArithmeticProgrammingReference》、《IntervalArithmeticSolvesNonlinearProblemsWhileProvidingGuaranteedResults》(http://www.
sun.
com/forte/info/features/intervals.
html)和-library.
A.
2.
127-xinline[=func_spec[,func_spec.
.
.
]]指定在-xO3或更高的优化级别优化器可以内联用户编写的哪些例程.
A.
2.
127.
1值func_spec必须是下列值之一.
表A–34-xinline值值含义%auto在-xO4或更高的优化级别上启用自动内联.
此参数告知优化器它可以内联所选择的函数.
请注意,如果没有指定%auto,则在命令行上使用-xinline=[no%]func_name.
.
.
指定显式内联后,通常会禁用自动内联.
A.
2选项参考附录AC++编译器选项279表A–34-xinline值(续)值含义func_name强烈请求优化器内联函数.
如果函数未声明为extern"C",则必须损坏func_name的值.
可以对可执行文件使用nm命令来查找损坏的函数名.
对于已声明为extern"C"的函数,编译器不损坏名称.
no%func_name如果为列表上的例程添加名称前缀no%,则会禁止内联该例程.
关于func_name的损坏名的规则也适用于no%func_name.
只有使用了-xcrossfile[=1]时,才会链接要编译的文件中的例程.
优化器决定适合内联的例程.
缺省值如果未指定-xinline选项,则编译器假定-xinline=%auto.
如果指定了没有任何参数的-xinline=,则不内联函数,而不管优化级别是什么.
示例要启用自动内联同时禁用内联声明为intfoo()的函数,请使用example%CC-xO5-xinline=%auto,no%__1cDfoo6F_i_-ca.
cc要强烈要求内联声明为intfoo()的函数,并使所有其他函数作为要内联的候选函数,请使用example%CC-xO5-xinline=%auto,__1cDfoo6F_i_-ca.
cc要强烈要求内联声明为intfoo()的函数,且不允许内联任何其他函数,请使用example%CC-xO5-xinline=__1cDfoo6F_i_-ca.
cc交互优化级别低于-xO3时,-xinline选项不起作用.
在-xO4或更高的优化级别上,优化器会决定应该内联哪些函数,无需指定-xinline选项即可完成.
另外,在-xO4或更高的优化级别上,编译器会尝试确定内联哪些函数可以提高性能.
如果出现以下任一情况,则不内联例程.
不会省略任何警告.
优化级别低于-xO3无法找到例程内联无益或不安全源代码不在要编译的文件中,或者使用了-xcrossfile[=1]时,源代码不在命令行上指定的文件中A.
2选项参考SunStudio12:C++用户指南280警告如果使用-xinline强制内联函数,实际上可能会降低性能.
另请参见第286页中的"A.
2.
133-xldscope={v}"A.
2.
128-xinstrument=[no%]datarace指定此选项以便编译和检测您的程序,以便由线程分析器进行分析.
有关线程分析器的更多详细信息,请参见tha(1).
然后可使用性能分析器以collect-rraces来运行此检测的程序,从而创建数据竞争检测实验.
也可以单独运行检测代码,但此运行很慢.
可指定-xinstrument=no%datarace来关闭线程分析器的源代码准备.
这是缺省设置.
指定-xinstrument而不带参数是非法操作.
如果在不同的步骤中进行编译和链接,则在编译和链接步骤都必须指定-xinstrument=datarace.
此选项定义预处理器标记__THA_NOTIFY.
可指定#ifdef__THA_NOTIFY来保护对libtha(3)例程的调用.
该选项也设置-g.
A.
2.
129-xipo[={0|1|2}]执行过程间优化.
-xipo选项通过调用过程间分析传递来执行部分程序优化.
与-xcrossfile不同,-xipo会对链接步骤中的所有目标文件执行优化,且优化不限于只是编译命令中的那些源文件.
但是,和-xcrossfile一样,使用-xipo执行的整个程序优化不包括汇编(.
s)源文件.
编译和链接大型多文件应用程序时,-xipo选项特别有用.
用该标志编译的对象目标文件具有在这些文件内编译的分析信息,这些信息实现了在源代码和预编译的程序文件中的过程间分析.
但分析和优化只限于使用-xipo编译的目标文件,并不扩展到目标文件或库.
A.
2.
129.
1值-xipo选项可以是下列值.
A.
2选项参考附录AC++编译器选项281表A–35-xipo值值含义0不执行过程间的优化1执行过程间的优化2执行过程间的别名分析和内存分配及布局的优化,以提高缓存的性能缺省值如果未指定-xipo,则假定-xipo=0.
如果仅指定了-xipo,则假定-xipo=1.
示例以下示例在相同的步骤中编译和链接.
example%CC-xipo-xO4-oprogpart1.
ccpart2.
ccpart3.
cc优化器在三个源文件之间执行交叉文件内联.
这在链接的最后一步完成,因此不必在一次编译所有源文件,可以分多次单独进行编译,每次编译时都指定-xipo选项.
以下示例在不同的步骤中编译和链接.
example%CC-xipo-xO4-cpart1.
ccpart2.
ccexample%CC-xipo-xO4-cpart3.
ccexample%CC-xipo-xO4-oprogpart1.
opart2.
opart3.
o在编译步骤中创建的目标文件具有在文件内部编译的附加分析信息,这样就可以在链接步骤中执行跨文件优化.
交互-xipo选项要求优化级别至少为-xO4.
不能在同一编译器命令行上同时使用-xipo选项和-xcrossfile选项.
警告在不同的步骤中进行编译和链接时,必须在这两个步骤中都指定-xipo才有效.
没有使用-xipo编译的对象可以自由地与使用-xipo编译的对象链接.
即使使用-xipo对库进行了编译,这些库也不参与交叉文件的过程间分析,如以下示例中所示.
A.
2选项参考SunStudio12:C++用户指南282example%CC-xipo-xO4one.
cctwo.
ccthree.
ccexample%CC-xar-omylib.
aone.
otwo.
othree.
o.
.
.
example%CC-xipo-xO4-omyprogmain.
ccfour.
ccmylib.
a本示例中,在one.
cc、two.
cc和three.
cc之间以及main.
cc和four.
cc之间执行过程间优化,但不在main.
cc或four.
cc和mylib.
a中的例程之间执行过程间优化.
(第一个编译可能生成有关未定义符号的警告,但仍可执行过程间优化,因为过程间优化是编译和链接的一个步骤.
)由于跨文件执行优化时需要附加信息,因此-xipo选项会生成更大的目标文件.
不过,该附加信息不会成为最后可执行的二进制文件的一部分.
可执行程序大小的增加都是由于执行的附加优化导致的.
A.
2.
129.
2何时不使用-xipo=2过程间分析在链接步骤中使用目标文件集合时,编译器试图执行整个程序分析和优化.
对于该目标文件集合中定义的任何函数或子例程foo(),编译器做出以下两个假定:运行时在该目标文件集合之外定义的其他例程不显式调用foo().
该目标文件集合中的任何例程调用foo()时,不会插入该目标文件集合之外定义的不同版本的foo().
如果假定1对于给定的应用程序不成立,请勿使用-xipo=2进行编译.
如果假定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()中,从而导致出现错误的结果.
另请参见-xjobsA.
2.
130-xipo_archive=[a]-xipo_archive选项使编译器可在生成可执行文件之前用通过-xipo编译的目标文件以及归档库(.
a)中的目标文件来优化传递给链接程序的目标文件.
库中包含的在编译期间优化的任何目标文件都会替换为其优化后的版本.
A.
2选项参考附录AC++编译器选项283a是以下项之一:表A–36-xipo_archive标志值含义writeback编译器在生成可执行文件前用通过-xipo优化并驻留在归档库(.
a)中的目标文件来优化传递给链接程序的目标文件.
库中包含的在编译期间优化的任何目标文件都会替换为优化后的版本.
对于使用归档库的公用集的并行链接,每个链接都应创建自己的归档库副本,以便在链接前优化.
readonly编译器在生成可执行文件前用通过-xipo优化并驻留在归档库(.
a)中的目标文件来优化传递给链接程序的目标文件.
通过-xipo_archive=readonly选项,可在链接时指定的归档库中进行对象文件的跨模块内联和程序间数据流分析.
但是,它不会启用归档库代码的跨模块优化,除非该代码已通过跨模块内联插入到其他模块中.
要对归档库内的代码应用跨模块优化,要求-xipo_archive=writeback.
请注意,执行此操作会修改从中提取代码的归档库的内容.
none这是缺省设置.
没有对归档文件的处理.
编译器不对使用-xipo编译和在链接时从归档库中提取的对象文件应用跨模块内联或其他跨模块优化.
要执行此操作,链接时必须指定-xipo,以及-xipo_archive=readonly或-xipo_archive=writeback中的任一个.
如果不为-xipo_archive指定设置,编译器会将其设置为-xipo_archive=none.
指定不带标志的-xipo_archive是非法的.
A.
2.
131-xjobs=n指定-xjobs选项设置编译器为完成其工作创建的进程数.
在多CPU计算机上,该选项可以缩短生成时间.
目前,-xjobs只能与-xipo选项一起使用.
如果指定-xjobs=n,过程间优化器在编译不同的文件时会用n作为它能调用的代码生成器实例的最大数目.
A.
2.
131.
1值指定-xjobs时务必要指定值.
否则,会发出错误诊断,并且编译中止.
通常,n的安全值等于1.
5乘以可用处理器数.
如果使用的值是可用处理器数的数倍,则会降低性能,因为有在产生的作业间进行的上下文切换开销.
此外,使用很大的数值会耗尽有限的系统资源(如交换空间).
A.
2选项参考SunStudio12:C++用户指南284缺省值出现最合适的实例之前,-xjobs的多重实例在命令行上会互相覆盖.
示例以下示例在有两个处理器的系统上进行的编译,速度比使用相同命令但没有-xjobs选项时进行的编译快.
example%CC-xipo-xO4-xjobs=3t1.
cct2.
cct3.
ccA.
2.
132-xlang=language[,language]包含适当的运行时库,并确保指定语言的适当运行时环境.
A.
2.
132.
1值language必须是f77、f90、f95或c99.
f90和f95参数等价.
c99参数表示为已使用-xc99=%all编译并要使用CC链接的对象调用ISO9899:1999C编程语言行为.
交互-xlang=f90和-xlang=f95选项隐含了-library=f90,而-xlang=f77选项隐含了-library=f77.
但要进行混合语言链接,只使用-library=f77和-library=f90选项是不够的,因为只有-xlang选项才能确保适当的运行时环境.
要决定在混合语言链接中使用的驱动程序,请使用下列语言分层结构:1.
C++2.
Fortran95(或Fortran90)3.
Fortran774.
C或C99将Fortran95、Fortran77和C++目标文件链接在一起时,请使用最高级语言的驱动程序.
例如,使用下列C++编译器命令来链接C++和Fortran95目标文件.
example%CC-xlang=f95.
.
.
要链接Fortran95和Fortran77目标文件,请使用如下所示的Fortran95驱动程序.
example%f95-xlang=f77.
.
.
不能在同一编译器命令中同时使用-xlang选项和-xlic_lib选项.
如果要使用-xlang且需要在Sun性能库中进行链接,应改用-library=sunperf.
A.
2选项参考附录AC++编译器选项285警告请勿将-xnolib与-xlang一起使用.
如果要将并行的Fortran对象与C++对象混合,链接行必须指定-mt标志.
另请参见-library和-staticlibA.
2.
133-xldscope={v}可指定-xldscope选项来更改外部符号定义的缺省链接程序作用域.
由于更好的隐藏了实现,所以对缺省的更改会产生更快速更安全的共享库和可执行文件.
A.
2.
133.
1值v必须是下列值之一:表A–37-xldscope值值含义global全局链接程序作用域是限制最少的链接程序作用域.
对符号的所有引用都绑定到定义符号的第一个动态装入模块中的定义.
该链接程序作用域是外部符号的当前链接程序作用域.
symbolic符号链接程序作用域比全局链接程序作用域具有更多的限制.
将对链接的动态装入模块内符号的所有引用绑定到模块内定义的符号.
在模块外部,符号也显示为全局符号.
该链接程序作用域对应于链接程序选项-Bsymbolic.
尽管不能将-Bsymbolic与C++库一起使用,但可以使用-xldscope=symbolic,而不会引起问题.
有关链接程序的更多信息,请参见ld(1).
hidden隐藏链接程序作用域具有比符号和全局链接程序作用域更高的限制.
将动态装入模块内的所有引用绑定到该模块内的定义.
符号在模块外部是不可视的.
缺省值如果未指定-xldscope,编译器将假定-xldscope=global.
如果指定了没有任何值的-xldscope,则编译器就会发出错误.
出现最合适的实例之前,该选项的多重实例在命令行上会互相覆盖.
警告如果要使客户端覆盖库中的函数,就必须确保该库生成期间未以内联方式生成该函数.
如果使用-xinline指定函数名、在可以自动进行内联的-xO4或更高优化级别进行编译、使用内联说明符或者要使用跨文件优化,编译器会内联函数.
A.
2选项参考SunStudio12:C++用户指南286例如,假定库ABC具有缺省的分配器函数,该函数可用于库的客户端,也可在库的内部使用:void*ABC_allocator(size_tsize){returnmalloc(size);}如果在-xO4或更高级别生成库,则编译器将内联库组件中出现的对ABC_allocator的调用.
如果库的客户端要用定制的版本替换ABC_allocator,则在调用ABC_allocator的库组件中不能进行该替换.
最终程序将包括函数的不同版本.
生成库时,用__hidden或__symbolic说明符声明的库函数可以内联生成.
假定这些库函数不被客户端覆盖.
请参见第62页中的"4.
2线程局部存储".
用__global说明符声明的库函数不应内联声明,并且应该使用-xinline编译器选项来防止内联.
另请参见-xinline、-xO和-xcrossfile.
A.
2.
134–xlibmieee使libm在异常情况下对于数学例程返回IEEE754值.
libm的缺省行为是兼容XPG.
A.
2.
134.
1另请参见《数值计算指南》A.
2.
135–xlibmil内联选定的libm库例程以进行优化.
注–该选项不影响C++内联函数.
有一些可用于部分libm库例程的内联模板.
该选项为当前使用的浮点选项和平台选择这些内联模板,生成执行速度最快的可执行文件.
A.
2.
135.
1交互–fast选项隐含了该选项.
另请参见-fast和《数值计算指南》.
A.
2选项参考附录AC++编译器选项287A.
2.
136–xlibmopt使用优化的数学例程库.
使用此选项时,必须通过指定-fround=nearest来使用缺省的舍入模式.
此选项使用经过了性能优化的数学例程库,通常情况下,生成的代码运行速度较快.
这样生成的代码可能与普通数学库生成的代码稍有不同,不同之处通常在最后一位上.
该库选项在命令行上的顺序并不重要.
A.
2.
136.
1交互–fast选项隐含了该选项.
另请参见–fast、–xnolibmopt和-froundA.
2.
137–xlic_lib=sunperf已过时,不使用.
改为指定-library=sunperf.
有关更多信息,请参见第232页中的"A.
2.
49-library=l[,l.
.
.
]".
A.
2.
138–xlicinfo编译器忽略此选项且不显示任何提示.
A.
2.
139-xlinkopt[=level]指示编译器在对目标文件进行优化的基础上对生成的可执行文件或动态库执行链接时优化.
这些优化在链接时通过分析二进制目标代码来执行.
虽然未重写目标文件,但生成的可执行代码可能与初始目标代码不同.
必须至少在部分编译命令中使用-xlinkopt,才能使-xlinkopt在链接时有效.
优化器仍可以对未使用-xlinkopt进行编译的二进制目标文件执行部分受限的优化.
-xlinkopt优化出现在编译器命令行上的静态库代码,但会跳过出现在命令行上的共享(动态)库代码而不对其进行优化.
生成共享库时(使用-G编译),也可以使用-xlinkopt.
A.
2.
139.
1值级别必须将执行的优化级别设置为0、1或2.
各优化级别如下所示:A.
2选项参考SunStudio12:C++用户指南288表A–38-xlinkopt值值含义0禁用链接优化器.
(这是缺省情况.
)1在链接时根据控制流分析执行优化,包括指令高速缓存着色和分支优化.
2在链接时执行附加的数据流分析,包括无用代码删除和地址计算简化.
如果在不同的步骤中编译,-xbinopt必须同时出现在编译和链接步骤中:example%cc-c-xlinkopta.
cb.
cexample%cc-omyprog-xlinkopt=2a.
o注意,仅当链接编译器时才使用级别参数.
在以上示例中,即使编译二进制目标文件时使用的是隐含的级别1,链接优化器的级别仍然是2.
缺省值指定-xlinkopt时若不带级别参数,则表示-xlinkopt=1.
交互当编译整个程序并且使用配置文件反馈时,该选项才最有效.
文件配置会显示代码中最常用和最少用的部分并相应地指导优化器集中其努力方向.
这对大型应用非常重要,因为链接时执行代码的优化放置可以减少指令的高速缓存缺失.
通常,编译如下所示:example%cc-oprogt-xO5-xprofile=collect:progfile.
cexample%progtexample%cc-oprog-xO5-xprofile=use:prog-xlinkoptfile.
c有关使用配置文件反馈的详细信息,请参见第311页中的"A.
2.
162-xprofile=p".
警告使用-xlinkopt编译时,请不要使用-zcompreloc链接程序选项.
注意,使用该选项编译会略微延长链接的时间,也会增加目标文件的大小,但可执行文件的大小保持不变.
使用-xlinkopt和-g编译会将调试信息包括在内,从而增加了可执行文件的大小.
A.
2选项参考附录AC++编译器选项289A.
2.
140–xM对指定的C++程序只运行预处理程序,同时请求该程序生成makefile依赖性并将结果发送到标准输出(有关make文件和依赖性的详细信息,请参见make(1)).
A.
2.
140.
1示例例如:#includevoidmain(void){}生成的输出如下:e.
o:e.
ce.
o:/usr/include/unistd.
he.
o:/usr/include/sys/types.
he.
o:/usr/include/sys/machtypes.
he.
o:/usr/include/sys/select.
he.
o:/usr/include/sys/time.
he.
o:/usr/include/sys/types.
he.
o:/usr/include/sys/time.
he.
o:/usr/include/sys/unistd.
h另请参见make(1S)(了解有关makefile和依赖性的详细信息).
A.
2.
141-xM1该选项与–xM相同,只是它不报告/usr/include头文件的依赖性,也不报告编译器提供的头文件的依赖性.
A.
2.
142–xMergeSPARC:将数据段和文本段合并.
目标文件中的数据是只读数据,并在进程之间共享,除非使用ld-N进行链接.
A.
2.
142.
1另请参见ld(1)手册页.
A.
2选项参考SunStudio12:C++用户指南290A.
2.
143-xmaxopt[=v]此命令将pragmaopt的级别限制为指定的级别.
v可以为off、1、2、3、4或5.
缺省值为-xmaxopt=off,表示忽略pragmaopt.
如果指定-xmaxopt但未提供参数,相当于指定-xmaxopt=5.
如果同时指定了-xO和-xmaxopt,则使用-xO设置的优化级别不能超过-xmaxopt值.
A.
2.
144-xmemalign=ab(SPARC)使用-xmemalign选项控制编译器对数据对齐所做的假定.
通过控制可能会出现非对齐内存访问的代码和出现非对齐内存访问时的处理程序,可以更轻松的将程序移植到SPARC.
指定最大假定内存对齐和非对齐数据访问的行为.
必须有一个同时用于a(对齐)和b(行为)的值.
a指定最大假定内存对齐,b指定未对齐内存访问行为.
对于可在编译时确定对齐的内存访问,编译器会为该数据对齐生成适当的装入/存储指令序列.
对于不能在编译时确定对齐的内存访问,编译器必须假定一个对齐以生成所需的装入/存储序列.
如果运行时的实际数据对齐小于指定的对齐,则未对齐的访问尝试(内存读取或写入)生成一个陷阱.
对陷阱的两种可能响应是操作系统将陷阱转换为SIGBUS信号.
如果程序无法捕捉到信号,则程序终止.
即使程序捕捉到信号,未对齐的访问尝试仍将无法成功.
操作系统通过翻译未对齐的访问并将控制返回给程序(仿佛访问已成功正常结束)来处理陷阱.
A.
2.
144.
1值下表列出了-xmemalign的对齐值和行为值.
表A–39-xmemalign对齐值和行为值ab1假定最多1字节对齐.
i解释访问并继续执行.
2假定最多2字节对齐.
s产生信号SIGBUS.
A.
2选项参考附录AC++编译器选项291表A–39-xmemalign对齐值和行为值(续)ab4假定最多4字节对齐.
f仅限于-xarch=v9变体:为小于或等于4的对齐产生信号SIGBUS,否则解释访问并继续执行.
对于其他所有-xarch值,f标志与i等效.
8假定最多8字节对齐.
16假定最多16字节对齐.
缺省值以下缺省值仅适用于未使用-xmemalign选项时:-xmemalgin=8i(适于所有v8体系结构).
-xmemalign=8s(适于所有v9体系结构).
在有-xmemalign选项但未提供值时,缺省值为:-xmemalign=1i(对于所有-xarch值).
示例下表说明了如何使用-xmemalign来处理不同的对齐情况.
表A–40-xmemalign示例命令情况-xmemalign=1s大量未对齐访问导致了自陷处理非常缓慢.
-xmemalign=8i在发生错误的代码中存在偶然的、有目的的、未对齐访问.
-xmemalign=8s程序中应该没有任何未对齐访问.
-xmemalin=2s要检查可能存在的奇字节访问.
-xmemalign=2i要检查可能存在的奇字节访问并要使程序工作.
A.
2.
145-xmodel=[a](x86)-xmodel选项让编译器可以针对Solarisx86平台修改64位对象形式,只应在要编译此类对象时指定该选项.
仅当启用了64位的x64处理器上还指定了-m64时,该选项才有效.
a必须是以下值之一:A.
2选项参考SunStudio12:C++用户指南292表A–41-xmodel标志值含义small此选项可为小模型生成代码,其中执行代码的虚拟地址在链接时已知,并且已知在0到2^31-2^24-1的虚拟地址范围内可以找到所有符号.
kernel按内核模型生成代码,在该模型中,所有符号都定义在2^64-2^31到2^64-2^24范围内.
medium按中等模型生成代码,在该模型中,不对数据段的符号引用范围进行假定.
文本段的大小和地址与小代码模型具有相同限制.
使用-m64编译时,具有大量静态数据的应用程序可能会要求-xmodel=medium.
此选项不累积,因此编译器根据命令行最右侧的-xmodel实例设置模型值.
如果未指定-xmodel,编译器将假定-xmodel=small.
指定不带参数的-xmodel是不正确的.
不必使用此选项编译所有转换单元.
只有可以确保访问的对象在可访问范围之内,才可编译选择的文件.
您应了解,不是所有的Linux系统都支持中等模型.
A.
2.
146–xnolib禁用与缺省系统库链接.
通常(不含该选项)情况下,C++编译器会链接多个系统库以支持C++程序.
使用该选项时,用于链接缺省系统支持库的-llib不会传递给ld.
通常情况下,编译器按照以下顺序链接系统支持库:在标准模式(缺省模式)下:-lCstd-lCrun-lm-lc兼容模式(-compat):-lC-lm-lc-l选项的顺序非常重要.
-lm选项必须位于-lc之前.
注–如果指定了-mt编译器选项,编译器通常先与-lthread链接,然后再与-lm链接.
A.
2选项参考附录AC++编译器选项293要确定在缺省情况下将链接哪些系统支持库,请使用-dryrun选项进行编译.
例如,以下命令的输出:example%CCfoo.
cc-xarch=v9-dryrun在输出中包括了以下内容:-lCstd-lCrun-lm-lcA.
2.
146.
1示例对于符合C应用程序二进制接口的基本编译(即只支持C所需的C++程序),请使用:example%CC–xnolibtest.
cc–lc要将libm静态链接到具有通用体系结构指令集的单线程应用程序中,请使用:标准模式下:example%CC-xnolibtest.
cc-lCstd-lCrun-Bstatic-lm-Bdynamic-lc兼容模式下:example%CC-compat-xnolibtest.
cc-lC-Bstatic-lm-Bdynamic-lc交互使用-xarch=v9、-xarch=v9a或-xarch=v9b链接时,某些静态系统库(如libm.
a和libc.
a)不可用.
如果指定了–xnolib,就必须按给定顺序手动链接所有必需的系统支持库.
必须最后链接系统支持库.
如果指定了-xnolib,则忽略-library.
警告许多C++语言功能要求使用libC(兼容模式)或libCrun(标准模式).
系统支持库的集合不稳定,会因不同的发行版本而更改.
另请参见–library、–staticlib和–l.
A.
2选项参考SunStudio12:C++用户指南294A.
2.
147–xnolibmil在命令行上取消–xlibmil.
将该选项与–fast一起使用会忽略与优化数学库链接.
A.
2.
148–xnolibmopt不使用数学例程库.
A.
2.
148.
1示例在命令行上–fast选项后面使用该选项,如下例中所示:example%CC–fast–xnolibmoptA.
2.
149-xnorunpath不将共享库的运行时搜索路径生成到可执行文件中.
通常cc不向链接程序传递任何-R路径.
有一些选项会向链接程序传递-R路径,如-xliclib=sunperf和-xopenmp.
可使用-xnorunpath选项来加以阻止.
建议用该选项生成提交到客户(这些客户的程序使用的共享库具有不同路径)的可执行文件.
A.
2.
150-xOlevel指定优化级别,请注意是大写字母O后跟数字1、2、3、4或5.
通常,程序执行速度取决于优化的级别.
优化级别越高,运行时性能越好.
不过,较高的优化级别会延长编译时间并生成较大的可执行文件.
在少数情况下,–xO2级别的执行可能比其他优化级别好,而–xO3也可能胜过–xO4.
尝试用每个级别进行编译,以查看您是否会遇到这种少见的情况.
如果优化器运行时内存不足,则会尝试在较低的优化等级上重试当前过程来恢复.
优化器会以在–xOlevel选项中指定的初始级别恢复执行后续过程.
–xO有五个级别.
以下几节描述了在SPARC平台和x86平台上如何操作这些级别.
A.
2.
150.
1值在SPARC平台上:A.
2选项参考附录AC++编译器选项295–xO1只执行最小量的优化(peephole),也称为postpass,即汇编级优化.
除非使用-xO2或-xO3导致编译时间过长,或交换空间不足,否则请勿使用-xO1.
–xO2执行基本的局部和全局优化,包括:归纳变量消除局部和全局的通用子表达式消除代数运算简化复制传播常量传播非循环变体优化寄存器分配基本块合并尾部递归消除终止代码消除尾部调用消除复杂表达式扩展该级别不优化外部变量或间接变量的引用或定义.
–xO3除了执行在–xO2级别所执行的优化外,还会对外部变量的引用和定义进行优化.
该级别不跟踪指针赋值的结果.
编译未通过volatile适当保护的设备驱动程序或修改来自信号处理程序中的外部变量的程序时,请使用–xO2.
通常,使用此级别时会增加代码大小,除非将其与-xspace选项结合使用.
–xO4除了执行–xO3优化外,还自动内联同一文件中的多个函数.
自动内联通常会提高执行速度,但有时却会使速度变得更慢.
通常,使用此级别时会增加代码大小,除非将其与-xspace选项结合使用.
–xO5生成最高级别的优化.
它只适用于占用大量计算机时间的小部分程序.
该级别采用了占用更多编译时间或无法在某种程度上减少执行时间的优化算法.
如果使用配置文件反馈执行该级别上的优化,则更容易提高性能.
请参见第311页中的"A.
2.
162-xprofile=p".
在x86平台上:–xO1执行基本优化.
其中包括代数运算简化、寄存器分配、基本块合并、终止代码和存储消除以及peephole优化.
–xO2执行局部通用子表达式消除、局部复制和常量传播、尾部递归消除以及级别1执行的优化.
–xO3执行全局通用子表达式的消除、全局复制和常量传播、循环长度约简、归纳变量消除、循环变体优化以及级别2执行的优化.
A.
2选项参考SunStudio12:C++用户指南296–xO4自动内联同一文件中的多个函数和级别3执行的优化.
这种自动内联通常会提高执行速度,但有时却会降低速度.
该级别还释放了通用的框架指针注册(ebp).
通常该级别会增加代码的大小.
–xO5生成最高级别的优化.
该级别采用了占用更多编译时间或无法在某种程度上减少执行时间的优化算法.
交互如果使用-g或-g0且优化级别是-xO3或更低,编译器会为近乎完全优化提供尽可能多的符号信息.
尾部调用优化和后端内联被禁用.
如果使用-g或-g0且优化级别是-xO4或更高,编译器会为完全优化提高尽可能多的符号信息.
使用-g进行调试不会抑制–xOlevel,但–xOlevel会对–g造成一些限制.
例如,–xOlevel选项会降低调试的作用,因此无法显示dbx中的变量,但仍可使用dbxwhere命令获取符号回溯.
有关更多信息,请参见《使用dbx调试程序》.
-xcrossfile选项只有与-xO4或-xO5一起使用时才有效.
优化级别低于-xO3时,-xinline选项不起作用.
优化级别为-xO4时,优化器会决定应该内联哪些函数,而不管是否指定了-xinline选项.
优化级别为-xO4时,编译器还会尝试确定内联哪些函数可以提高性能.
如果使用-xinline强制内联函数,实际上可能会降低性能.
缺省值缺省为不优化.
不过,只有不指定优化级别时才可能使用缺省设置.
如果指定了优化级别,则没有任何选项可用来关闭优化.
如果尝试不设置优化级别,请不要指定任何隐含优化级别的选项.
例如,-fast是将优化级别设置为-xO5的宏选项.
隐含优化级别的所有其他选项都会给出优化已设置的警告消息.
不使用任何优化来编译的方法是从命令行删除所有选项或创建指定优化级别的文件.
警告如果在–xO3或–xO4级别上优化多个非常大的过程(一个过程有数千行代码),编译器会需要过多内存.
在这些情况下,机器的性能就会降低.
为了防止性能降低,请使用limit命令限制单一进程可用的虚拟内存大小(请参见csh(1)手册页).
例如,将虚拟内存限制为16MB:example%limitdatasize16M如果虚拟内存达到16MB的数据空间,该命令会使优化器尝试恢复.
A.
2选项参考附录AC++编译器选项297限制不能大于机器总的可用交换空间,而且要足够的小以允许在大型编译的过程中机器可以正常使用.
数据大小的最佳设置取决于要求的优化程度、真实内存和可用虚拟内存的大小.
要查找实际的交换空间,请输入:swap–l要查找实际的真实内存,请输入:dmesg|grepmem另请参见-xldscope–fast、-xcrossfile=n、–xprofile=p和csh(1)手册页A.
2.
151-xopenmp[=i]使用-xopenmp选项可通过OpenMP指令进行显式并行化.
要在多线程环境中运行已并行化的程序,必须在执行之前设置OMP_NUM_THREADS环境变量.
要启用嵌套并行操作,必须将OMP_NESTED环境变量设置为TRUE.
缺省情况下,禁用嵌套并行操作.
A.
2.
151.
1值下表列出了i值:表A–42-xopenmp值值含义parallel启用OpenMPpragma的识别.
在-xopenmp=parallel时,最低优化级别是-x03.
编译器会在必要时将优化级别提高到-x03并发出警告.
此标志还定义处理器标记_OPENMP.
noopt启用OpenMPpragma的识别.
如果优化级别低于-O3,编译器将不会提高优化级别.
如果显式将优化级别设置为低于-O3(如CC-O2-xopenmp=noopt),编译器会发出错误.
如果没有使用-xopenmp=noopt指定优化级别,则会识别OpenMPpragma,并相应地对程序进行并行处理,但不进行优化.
此标志还定义处理器标记_OPENMP.
none此标记是缺省的,它禁用对OpenMPpragma的识别,而且不更改程序的优化级别且不预定义任何预处理程序标记.
A.
2选项参考SunStudio12:C++用户指南298缺省值如果未指定-xopenmp,则编译器将该选项设置为-xopenmp=none.
如果指定了没有参数的-xopenmp,则编译器将该选项设置为-xopenmp=parallel.
交互如果使用dbx调试OpenMP程序,那么编译时选用-g和-xopenmp=noopt可以在并行区设置断点并显示变量内容.
警告请不要将-xopenmp和-xexplicitpar或-xparallel一起指定.
在以后的发行版中,-xopenmp的缺省值可能会更改.
可以通过显式指定适当的优化来避免警告消息.
如果在不同的步骤中进行编译和链接,请在编译步骤和链接步骤中都指定-xopenmp.
如果要生成共享对象,这很重要.
用于编译可执行文件的编译器的版本不得比使用-xopenmp生成.
so的编译器低.
这在编译包含OpenMP指令的库时尤其重要.
为了取得最佳的性能,请确保在系统上安装了最新的OpenMP运行时库libmtsk.
so.
另请参见有关生成多进程应用程序的OpenMPFortran95、C和C++应用程序接口(applicationprograminterface,API)的完整摘要,请参见《SunStudio12:OpenMPAPIUser'sGuide》.
A.
2.
152-xpagesize=n为栈和堆设置首选页面大小.
A.
2.
152.
1值n值必须是以下项之一:4k、8K、64K、512K、2M、4M、32M、256M、2G、16G或default.
必须指定适于目标平台的有效页面大小.
如果您不指定有效的页面大小,则运行时请求就会被忽略.
在Solaris操作系统中使用getpagesize(3C)命令可以确定页面中的字节数.
Solaris操作系统不保证支持页面大小请求.
可以使用pmap(1)或meminfo(2)来确定目标平台的页面大小.
A.
2选项参考附录AC++编译器选项299注–该功能只在Solaris8操作系统中可用.
在Solaris8软件上不链接使用该选项编译的程序.
缺省值如果指定-xpagesize=default,Solaris操作系统将设置页面大小.
扩展此选项是用于-xpagesize_heap和-xpagesize_stack的宏.
这两个选项与-xpagesize接受相同的参数:4k、8K、64K、512K、2M、4M、32M、256M、2G、16G或default.
可以通过指定-xpagesize为它们设置相同值,也可以分别为它们指定不同的值.
警告除非在编译和链接时使用,否则-xpagesize选项不会生效.
另请参见使用该选项进行编译与使用等效的选项将LD_PRELOAD环境变量设置为mpss.
so.
1或在运行程序之前使用等效的选项运行Solaris9命令ppgsz(1)具有相同的效果.
有关详细信息,请参见Solaris手册页.
A.
2.
153-xpagesize_heap=n为堆设置内存页面大小.
A.
2.
153.
1值n可以是4k、8K、64K、512K、2M、4M、32M、256M、2G、16G或default.
必须指定适于目标平台的有效页面大小.
如果不指定有效的页面大小,运行时将忽略该请求,且不显示任何提示.
在Solaris操作系统中使用getpagesize(3C)命令可以确定页面中的字节数.
Solaris操作系统不保证支持页面大小请求.
可以使用pmap(1)或meminfo(2)来确定目标平台的页面大小.
注–该功能只在Solaris8操作系统中可用.
在Solaris8软件上不链接使用该选项编译的程序.
缺省值如果指定-xpagesize_heap=default,Solaris操作系统将设置页面大小.
A.
2选项参考SunStudio12:C++用户指南300警告除非在编译和链接时使用,否则-xpagesize_heap选项不会生效.
另请参见使用该选项进行编译与使用等效的选项将LD_PRELOAD环境变量设置为mpss.
so.
1或在运行程序之前使用等效的选项运行Solaris9命令ppgsz(1)具有相同的效果.
有关详细信息,请参见Solaris手册页.
A.
2.
154-xpagesize_stack=n为栈设置内存页面大小.
A.
2.
154.
1值n可以是4k、8K、64K、512K、2M、4M、32M、256M、2G、16G或default.
必须指定适于目标平台的有效页面大小.
如果不指定有效的页面大小,运行时将忽略该请求,且不显示任何提示.
在Solaris操作系统中使用getpagesize(3C)命令可以确定页面中的字节数.
Solaris操作系统不保证支持页面大小请求.
可以使用pmap(1)或meminfo(2)来确定目标平台的页面大小.
注–该功能只在Solaris8操作系统中可用.
在Solaris8软件上不链接使用该选项编译的程序.
缺省值如果指定-xpagesize_stack=default,Solaris操作系统将设置页面大小.
警告除非在编译和链接时使用,否则-xpagesize_stack选项不会生效.
另请参见使用该选项进行编译与使用等效的选项将LD_PRELOAD环境变量设置为mpss.
so.
1或在运行程序之前使用等效的选项运行Solaris9命令ppgsz(1)具有相同的效果.
有关详细信息,请参见Solaris手册页.
A.
2选项参考附录AC++编译器选项301A.
2.
155-xpch=v该编译器选项激活了预编译头文件特性.
预编译头文件的作用是减少源代码共享同一组include文件的应用程序的编译时间,而且这些include文件往往有大量的源代码.
编译器首先从一个源文件收集一组头文件信息,然后在重新编译该源文件或者其他有同样头文件的源文件时就可以使用这些收集到的信息.
编译器收集的信息存储在预编译头文件中.
要使用该功能,需要指定-xpch和-xpchstop选项,并使用#pragmahdrstop指令.
另请参见:第304页中的"A.
2.
156-xpchstop=file"第338页中的"B.
2.
8#pragmahdrstop"A.
2.
155.
1创建预编译头文件-xpch=v中的v可以是collect:pch_filename或use:pch_filename.
首次使用-xpch时,必须指定collect模式.
指定-xpch=collect的编译命令只能指定一个源文件.
在以下示例中,-xpch选项根据源文件a.
cc创建名为myheader.
Cpch的预编译头文件:CC-xpch=collect:myheadera.
cc有效的预编译头文件总是有后缀.
Cpch.
在指定pch_filename时,后缀可以由您自己增加或由编译器增加.
例如,如果指定cc-xpch=collect:fooa.
cc,则预编译头文件称为foo.
Cpch.
在创建预编译头文件时,请选取包含所有源文件之间include文件通用序列的源文件,预编译头文件与这些源文件一起使用.
include文件的共同序列在这些源文件之间必须是一样的.
请记住,在collect模式中只能使用一个源文件名值.
例如,CC-xpch=collect:foobar.
cc有效,而CC-xpch=collect:foobar.
ccfoobar.
cc无效,因为它指定了两个源文件.
使用预编译头文件可指定-xpch=use:pch_filename以使用预编译头文件.
您可以将include文件同一序列中任意数量的源文件指定为用于创建预编译头文件的源文件.
例如,在use模式中命令类似于:CC-xpch=use:foo.
Cpchfoo.
cbar.
ccfoobar.
cc.
如果下列情况为真,就只应使用现有的预编译头文件.
如果以下任意条件不成立,则应重新创建预编译头文件:用于访问预编译头文件的编译器与创建预编译头文件的编译器相同.
编译器的一个版本创建的预编译头文件可能无法用于另一版本(包括安装的修补程序产生的差异).
除-xpch选项之外,用-xpch=use指定的编译器选项必须与创建预编译头文件时指定的选项相匹配.
A.
2选项参考SunStudio12:C++用户指南302用-xpch=use指定的包含头文件的集合与创建预编译头文件时指定的头文件集合是相同的.
用-xpch=use指定的包含头文件的内容与创建预编译头文件时指定的包含头文件的内容是相同的.
当前目录(即发生编译并尝试使用给定预编译头文件的目录)与创建预编译头文件所在的目录相同.
在用-xpch=collect指定的文件中预处理指令(包括#include)的初始序列,与在用-xpch=use指定的文件中预处理指令的序列相同.
要在多个源文件间共享预编译头文件,这些源文件必须共享一组共同的include文件(按其初始标记序列).
该初始标记序列称为活前缀.
活前缀必须在使用相同预编译头文件的所有源文件中解释一致.
源文件的活前缀只能包含注释和以下任意预处理程序指令:#include#if/ifdef/ifndef/else/elif/endif#define/undef#ident(ifidentical,passedthroughasis)#pragma(ifidentical)以上任何指令都可以引用宏.
#else、#elif和#endif指令必须在活前缀内匹配.
在共享预编译头文件的每个文件的活前缀中,每个相应的#define和#undef指令都必须引用相同的符号(例如每个#define必须引用同一个值).
这些指令在每个活前缀中出现的顺序也必须相同.
每个相应pragma也必须相同,并且必须按相同顺序出现在共享预编译头文件的所有文件中.
并入预编译头文件的头文件一定不得违反以下约束.
这里没有定义对违反任意这些约束的程序的编译结果.
头文件一定不要包含函数和变量定义.
头文件不得使用__DATE__和__TIME__.
使用预处理宏会产生无法预料的结果.
头文件不得包含#pragmahdrstop.
头文件的活前缀中不得使用__LINE__和__FILE__.
但可以在包含头文件中使用__LINE__和__FILE__.
如何修改make文件下面是为了将-xpch合并到生成的程序中而对make文件进行修改的几种可能方法.
可以通过使用辅助变量CCFLAGS以及make和dmake的KEEP_STATE功能使用隐式make规则.
预编译头文件在独立的步骤中产生.
A.
2选项参考附录AC++编译器选项303.
KEEP_STATE:CCFLAGS_AUX=-OetcCCFLAGS=-xpch=use:shared$(CCFLAGS_AUX)shared.
Cpch:foo.
cc$(CCC)-xpch=collect:shared$(CCFLAGS_AUX)foo.
cca.
out:foo.
oping.
opong.
o$(CCC)foo.
oping.
opong.
o您还可以定义自己的编译规则,而无不是尝试使用辅助变量CCFLAGS.
.
KEEP_STATE:.
SUFFIXES:.
o.
cc%.
o:%.
ccshared.
Cpch$(CCC)-xpch=use:shared$(CCFLAGS)-c$#include#include"projectheader.
h"#include"privateheader.
h".
.
A.
2选项参考SunStudio12:C++用户指南304.
example%CC-xpch=collect:foo.
Cpcha.
cc-xpchstop=projectheader.
h-cA.
2.
156.
1另请参见-xpch和pragmahdrstop.
A.
2.
157–xpg编译以便使用gprof配置程序进行文件配置.
–xpg选项用于编译自配置代码来收集数据,以便使用gprof配置文件.
该选项调用运行时记录机制,该机制会在程序正常终止时生成gmon.
out文件.
注–如果指定-xpg,-xprofile将没有用处.
两者不能准备或使用对方提供的数据.
在64位Solaris平台上,使用prof(1)或gprof(1)生成配置文件,在32位Solaris平台上,则只使用gprof生成配置文件,配置文件中包括大概的用户CPU时间.
这些时间来自主可执行文件中的例程以及共享库中例程(链接可执行文件时将共享库指定为链接程序参数)的PC示例数据(请参见pcsample(2)).
其他共享库(在进程启动后使用dlopen(3DL)打开的库)不进行文件配置.
在32位Solaris系统中,使用prof(1)生成的配置文件仅限于可执行文件中的例程.
32位共享库通过用-xpg和gprof(1)链接可执行程序可以进行文件配置.
Solaris10软件不包括使用-p编译的系统库.
因此,在Solaris10平台上收集的配置文件不包括系统库例程的调用计数.
A.
2.
157.
1警告如果分别进行编译和链接,且使用–xpg进行编译,应确保使用–xpg进行链接.
另请参见–xprofile=p、analyzer(1)手册页和《性能分析器》手册.
A.
2.
158-xport64[=(v)]使用此选项可以帮助调试要移植到64位环境的代码.
具体来说,该选项会对以下情况提示警告信息:类型的截断(包括指针),符号扩展以及对位包装的更改.
将代码从诸如V7的32位体系结构移植到诸如V9的64位体系结构时,这些更改是很通常的.
A.
2.
158.
1值下表列出了v的有效值:A.
2选项参考附录AC++编译器选项305表A–43-xport64值值含义no将代码从32位环境移植到64位环境时,不会生成与该代码移植有关的任何警告.
implicit只生成隐式转换的警告.
显式强制类型转换出现时不生成警告.
full将代码从32位环境移植到64位环境时,生成了与该代码移植有关的所有警告.
其中包括对64位值的截断警告、根据ISO值的保存规则对64位的符号扩展,以及对位字段包装的更改.
缺省值如果未指定-xport64,则缺省值为-xport64=no.
如果指定了-xport64但未指定标志,则缺省值为-xport64=full.
示例本节提供了可以导致类型截断、符号扩展和对位包装更改的代码示例.
检查64位值的截断在移植到诸如V9的64位架构时,数据可能会被截断.
截断可能会因赋值(初始化时)或显式强制类型转换而隐式地发生.
两个指针的差异在于typedefptrdiff_t,它在32位模式下是32位整型,而在64位模式下是64位整型.
将较长的整型截断为较小的整型会生成警告,如下示例所示.
example%cattest1.
cintx[10];intdiff=&x[10]-&x[5];//warnexample%CC-c-xarch=v9-Qoptionccfe-xport64=fulltest1.
c"test1.
c",line3:Warning:Conversionof64-bittypevalueto"int"causestruncation.
1Warning(s)detected.
example%可使用-xport64=implicit禁用64位编译模式下显式强制类型转换导致数据截断时出现截断警告.
example%CC-c-xarch=v9-Qoptionccfe-xport64=implicittest1.
c"test1.
c",line3:Warning:Conversionof64-bittypevalueto"int"causestruncation.
1Warning(s)detected.
example%A.
2选项参考SunStudio12:C++用户指南306在移植到64位架构过程中出现的另一个常见问题是指针的截断.
该问题在C++中始终是错误.
如果指定-xport64,导致此类截断的操作(如将指针强制转换为整型)可能会导致在V9中出现错误诊断.
example%cattest2.
cchar*p;intmain(){p=(char*)(((unsignedint)p)&0xFF);//-xarch=v9errorreturn0;}example%CC-c-xarch=v9-Qoptionccfe-xport64=fulltest2.
c"test2.
c",line3:Error:Cannotcastfromchar*tounsigned.
1Error(s)detected.
example%检查符号扩展还可以使用-xport64选项来检查这种情况:标准ISOC值保留规则允许在无符号整型的表达式中进行带符号整数值的符号扩展.
这种符号扩展会产生细微的运行时错误.
example%cattest3.
cinti=-1;voidpromo(unsignedlongl){}intmain(){unsignedlongl;l=i;//warnpromo(i);//warn}example%CC-c-xarch=v9-Qoptionccfe-xport64=fulltest3.
c"test3.
c",line6:Warning:Signextensionfrom"int"to64-bitinteger.
"test3.
c",line7:Warning:Signextensionfrom"int"to64-bitinteger.
2Warning(s)detected.
检查位字段包装的更改可使用-xport64生成对长位字段的警告.
出现这种位字段时,位字段的包装可能会显著更改.
在成功移植到64位架构之前,依赖于假定的任何程序都需要重新检查,该假定与包装位字段的方法有关.
example%cattest4.
c#includeunionU{structS{unsignedlongb1:20;unsignedlongb2:20;A.
2选项参考附录AC++编译器选项307}s;longbuf[2];}u;intmain(){u.
s.
b1=0XFFFFF;u.
s.
b2=0XFFFFF;printf("u.
buf[0]=%lxu.
buf[1]=%lx\n",u.
buf[0],u.
buf[1]);return0;}example%V9中的输出:example%u.
buf[0]=ffffffffff000000u.
buf[1]=0警告请注意,仅当通过指定-m64等选项以64位模式编译时,才会生成警告.
另请参见第235页中的"A.
2.
50-m32|-m64"A.
2.
159-xprefetch[=a[,a.
.
.
]]SPARC:在支持预取的体系结构上启用预取指令.
显式预取只应在度量支持的特殊环境下使用.
a必须是下列值之一.
表A–44-xprefetch值值含义auto启用预取指令的自动生成no%auto禁用预取指令的自动生成explicit(SPARC)启用显式预取宏no%explicit(SPARC)禁用显式预取宏A.
2选项参考SunStudio12:C++用户指南308表A–44-xprefetch值(续)值含义latx:factor根据指定的因子,调整编译器假定的"预取到装入"和"预取到存储"延迟.
只能将此标志与-xprefetch=auto结合使用.
该因子必须是正浮点数或整数.
yes已废弃,不使用.
改用-xprefetch=auto,explicit.
no已废弃,不使用.
改用-xprefetch=no%auto,no%explicit.
使用-xprefetch、-xprefetch=auto和-xprefetch=yes,编译器就可以将预取指令自由插入到它生成的代码中.
该操作会提高支持预取的体系结构的性能.
如果要在较大的多处理器上运行计算密集的代码,您会发现使用-xprefetch=latx:factor有很多优点.
该选项指示代码生成器按照指定的因子调节预取与其相关的装入或存储之间的缺省延迟时间.
预取延迟是从执行预取指令到所预取的数据在高速缓存中可用那一刻之间的硬件延迟.
在确定发出预取指令到发出使用所预取数据的装入或存储指令之间的间隔时,编译器就采用预取延迟值.
注–在预取和装入之间采用的延迟可能与在预取和存储之间采用的延迟不同.
编译器可以在众多计算机与应用程序间调整预取机制,以获得最佳性能.
这种调整并非总能达到最优.
对于占用大量内存的应用程序,尤其是要在大型多处理器上运行的应用程序,可以通过增加预取延迟值来提高性能.
要增加值,请使用大于1的因子.
介于.
5和2.
0之间的值最有可能提供最佳性能.
对于数据集完全位于外部高速缓存中的应用程序,可以通过减小预取延迟值来提高性能.
要减小值,请使用小于1的因子.
要使用-xprefetch=latx:factor选项,请首先使用接近1.
0的因子值并对应用程序运行性能测试.
然后适当增加或减小该因子,并再次运行性能测试.
继续调整因子并运行性能测试,直到获得最佳性能.
以很小的增量逐渐增加或减小因子时,前几步中不会看到性能差异,之后会突然出现差异,然后再趋于稳定.
A.
2.
159.
1缺省值如果未指定-xprefetch,则假定为-xprefetch=no%auto,explicit.
如果仅指定了-xprefetch,则假定为-xprefetch=auto,explicit.
除非使用不带任何参数或具有auto或yes参数的-xprefetch进行显式覆盖,否则使用缺省值no%auto.
例如,-xprefetch=explicit与-xprefetch=explicit,no%auto相同.
除非使用参数no%explicit或no进行显式覆盖,否则使用缺省值explicit.
例如,-xprefetch=auto与-xprefetch=auto,explicit相同.
A.
2选项参考附录AC++编译器选项309如果启用了自动预取(例如,使用-xprefetch或-xprefetch=yes),但是未指定延迟因子,则假定-xprefetch=latx:1.
0.
交互该选项会累积而不覆盖.
sun_prefetch.
h头文件提供了用于指定显式预取指令的宏.
这些预取可能位于对应于宏出现位置的可执行文件中.
要使用显式预取指令,必须在适当的体系结构上包含sun_prefetch.
h,并且从编译器命令中排除-xprefetch或者使用-xprefetch、-xprefetch=auto,explicit、-xprefetch=explicit或-xprefetch=yes.
如果调用了宏并包含了sun_prefetch.
h头文件,但传递了-xprefetch=no%explicit或-xprefetch=no,那么显式预取将不会出现在可执行文件中.
只有启用了自动预取时,才可以使用latx:factor.
即,latx:factor只有与yes或auto结合使用时才有效,如-xprefetch=yes,latx:factor.
警告显式预取只应在度量支持的特殊环境下使用.
因为编译器可以在众多计算机与应用程序间调整预取机制以获得最佳性能,所以当性能测试指示性能明显提高时,应当只使用-xprefetch=latx:factor.
假定的预取延迟在不同发行版本中是不同的.
因此,无论何时切换到不同的发行版本,强烈建议重新测试延迟因子对性能的影响.
A.
2.
160-xprefetch_auto_type=a其中,a是[no%]indirect_array_access.
使用此选项可以确定编译器是否以为直接内存访问生成预取的方式为由选项-xprefetch_level指示的循环生成间接预取.
如果不指定-xprefetch_auto_type的设置,编译器会将其设置为-xprefetch_auto_type=no%indirect_array_access.
-xdepend、-xrestrict和-xalias_level等选项会影响计算候选间接预取的主动性,进而影响因更好的内存别名歧义消除信息而自动插入间接预取的主动性.
A.
2.
161-xprefetch_level[=i]可使用新的-xprefetch_level=i选项控制由-xprefetch=auto确定的自动插入预取指令的主动性.
编译器变得更加主动,也就是说,引入了更多预取级别-xprefetch_level(依次增高).
A.
2选项参考SunStudio12:C++用户指南310-xprefetch_level取何适当值取决于应用程序的高速缓存未命中次数.
-xprefetch_level值越高,越有可能提高那些高速缓存未命中次数较多的应用程序的性能.
A.
2.
161.
1值i必须是1、2或3.
表A–45-xprefecth_level值值含义1启用预取指令的自动生成.
2针对其他循环(超过在-xprefetch_level=1针对的循环)来插入预取.
插入的其他预取可超过在-xprefetch_level=1插入的预取.
3针对其他循环(超过在-xprefetch_level=2针对的循环)来插入预取.
插入的其他预取可超过在-xprefetch_level=2插入的预取.
缺省值指定了-xprefetch=auto时,缺省值为-xprefetch_level=1.
交互仅当使用-xprefetch=auto对该选项进行编译,优化级别为3或更高(-xO3),而且是在支持预取的平台(v8plus、v8plusa、v9、v9a、v9b、generic64、native64)上时,该选项才有效.
A.
2.
162-xprofile=p可使用该选项先收集并保存执行频率数据,这样便可以在后续运行中使用这些数据以提高性能.
只有将优化级别指定为-xO2或更高时,该选项才有效.
为编译器提供运行时性能反馈增强了在较高优化级别(如-xO5)进行编译的功能.
为了生成运行时的性能反馈,必须使用-xprofile=collect编译,然后针对典型数据集运行可执行文件,最后在最高的优化级别使用-xprofile=use重新编译.
对多线程应用程序来讲,配置文件集合是安全的.
也就是说,对执行自身多任务(-mt)的程序进行文件配置会产生准确的结果.
只有将优化级别指定为-xO2或更高时,该选项才有效.
A.
2.
162.
1值p必须是下列值之一.
collect[:name]A.
2选项参考附录AC++编译器选项311在–xprofile=use时优化器收集并保存执行频率,以供将来使用.
编译器生成测量语句执行频率的代码.
注–在Linux上生成共享库时,请勿指定-xprofile=collect.
name是所分析程序的名称.
name是可选的,如果没有指定,则假定为a.
out.
在运行时,使用–xprofile=collect:name编译的程序会创建子目录name.
profile来保存运行时反馈信息.
数据将写入该子目录下的文件feedback中.
可以使用环境变量$SUN_PROFDATA和$SUN_PROFDATA_DIR更改反馈信息的位置.
有关更多信息,请参见交互一节.
如果多次运行程序,执行频率数据会累积在feedback文件中,也就是说以前运行的输出不会丢失.
如果在不同的步骤中进行编译和链接,应确保使用-xprofile=collect编译的任何目标文件也使用-xprofile=collect进行链接.
use[:name]使用执行频率数据优化程序,这些数据是先前执行程序(使用–xprofile=collect编译)产生并保存在feedback文件中的.
name是要分析的可执行文件的名称.
name是可选的,如果没有指定,则假定为a.
out.
除了从-xprofile=collect更改为-xprofile=use的-xprofile选项之外,源文件和其他编译器选项必须与用于(创建了之后生成feedback文件的编译程序的)编译的源文件和编译器选项完全相同.
编译器的相同版本必须既用于收集生成也用于使用生成.
如果使用-xprofile=collect:name进行了编译,则在优化编译中必须使用相同的程序名称name:-xprofile=use:name.
目标文件与其配置文件数据之间的关联依据的是使用-xprofile=collect编译目标文件时该文件的UNIX路径名.
在某些情况下,编译器将不会关联目标文件和其配置文件数据:目标文件因以前没有使用-xprofile=collect进行编译而没有配置文件数据,未使用-xprofile=collect在程序中链接目标文件,从未执行过程序.
如果先前使用-xprofile=collect在不同目录中编译了目标文件,而该目标文件与使用-xprofile=collect编译的其他目标文件共享一个公共基名,但却无法通过它们的包含目录名称进行唯一标识,编译器也会产生混淆.
在这种情况下,即使目标文件有配置文件数据,使用-xprofile=use重新编译目标文件时,编译器也不能在feedback目录中找到该目标文件.
所有这些情况都能使编译器释放目标文件及其文件配置数据之间的关联.
因此,如果目标文件有配置文件数据,但在指定了-xprofile=use时,编译器无法将其与目标文件的路径名关联,请使用-xprofile_pathmap选项标识正确的目录.
请参见第314页中的"A.
2.
164-xprofile_pathmap"tcovA.
2选项参考SunStudio12:C++用户指南312使用新式tcov进行基本块覆盖分析.
此选项是tcov的新式基本块文件配置.
它的功能与–xa选项类似,但可以正确收集在头文件中有源代码或利用C++模板的程序的数据.
代码重构与-xa选项的代码指令类似,但不再生成.
d文件.
相反却生成单一文件,并且该文件的名称是按照最后的可执行文件命名的.
例如,如果程序在/foo/bar/myprog.
profile之外运行,那么数据文件将存储在/foo/bar/myprog.
profile/myprog.
tcovd中.
运行tcov时,必须将其传递给–x选项,以强制其使用新式数据.
如果未传递-x,则缺省情况下tcov使用原来的.
d文件,并生成意外的输出.
与–xa选项不同,环境变量TCOVDIR在编译时无效.
不过,在程序运行时可以使用环境变量的值.
交互–xprofile=tcov和-xa选项在单个可执行程序中兼容.
也就是说,可以链接同时包含了用-xprofile=tcov编译的某些文件和用-xa编译的另外一些文件的程序.
您不能同时用这两个选项来编译同一个文件.
如果因使用-xinline或-xO4而内联函数,那么-xprofile=tcov生成的代码覆盖报告不可靠.
可以设置环境变量$SUN_PROFDATA和$SUN_PROFDATA_DIR控制使用-xprofile=collect编译的程序放置配置文件数据的位置.
如果未设置这些变量,配置文件数据就写入当前目录中的name.
profile/feedback(name是可执行文件的名称或在-xprofile=collect:name标志中指定的名称).
如果设置了这些变量,-xprofile=collect数据就写入$SUN_PROFDATA_DIR/$SUN_PROFDATA.
环境变量$SUN_PROFDATA和$SUN_PROFDATA_DIR同样控制tcov生成的配置文件数据文件的路径和名称.
有关更多信息,请参见tcov(1)手册页.
警告如果在不同的步骤中进行编译和链接,则编译命令和链接命令中都必须有相同的-xprofile选项.
虽然只在一个步骤中包括-xprofile而在其他步骤中不包括该项不会影响程序的正确性,但这样将无法进行文件配置.
另请参见-xa、tcov(1)手册页和《程序性能分析工具》.
A.
2.
163-xprofile_ircache[=path](SPARC)将-xprofile_ircache[=path]与-xprofile=collect|use一起使用,并重新使用collect阶段保存的编译数据,以改善use阶段的编译时间.
A.
2选项参考附录AC++编译器选项313在编译大程序时,由于中间数据的保存,使得use阶段的编译时间大大减少.
注意,所保存的数据会占用相当大的磁盘空间.
在使用-xprofile_ircache[=path]时,path会覆盖保存缓存文件的位置.
缺省情况下,这些文件会作为目标文件保存在同一目录下.
collect和use阶段出现在两个不同目录中时,指定路径很有用.
以下是典型的命令序列:example%CC-xO5-xprofile=collect-xprofile_ircachet1.
cct2.
ccexample%a.
out//runcollectsfeedbackdataexample%CC-xO5-xprofile=use-xprofile_ircachet1.
cct2.
ccA.
2.
164-xprofile_pathmap(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与目标文件路径名也不匹配.
A.
2.
165–xregs=r[,r.
.
.
]控制临时寄存器的使用.
如果编译器可以使用更多的寄存器用于临时存储(临时寄存器),那么编译器将能生成速度更快的代码.
该选项使得附加临时寄存器可用,而这些附加寄存器通常是不适用的.
A.
2.
165.
1值r必须是下列值之一.
每个值的含义都与-xarch的设置相关.
A.
2选项参考SunStudio12:C++用户指南314表A–46-xregs值值含义[no%]appl(SPARC)[不]允许编译器将应用程序寄存器用作临时寄存器来生成代码.
应用程序寄存器是:g2、g3或g4(在32位平台上)g2或g3(在64位平台上)强烈建议使用-xregs=no%appl编译所有系统软件和库.
系统软件(包括共享库)必须为应用程序保留这些寄存器值.
这些值的使用将由编译系统控制,而且在整个应用程序中必须保持一致.
在SPARCABI中,这些寄存器表示为应用程序寄存器.
使用这些寄存器时需要的装入和存储指令较少,因此可以提高性能.
不过,这样使用会与将寄存器用于其他目的的程序发生冲突.
[no%]float(SPARC)[不]允许编译器通过将浮点寄存器用作整数值的临时寄存器来生成代码.
使用浮点值可能会用到与该选项无关的这些寄存器.
如果希望您的代码没有任何对浮点寄存器的引用,需要使用-xregs=no%float并确保您的代码不会以任何方式使用浮点类型.
[no%]frameptr(x86)[不]允许编译器将帧指针寄存器(IA32上的%ebp、AMD64上的%rbp)用作未分配的被调用方保存寄存器.
如果将此寄存器用作被调用方保存寄存器,则可提高程序运行时性能.
但是,它也会降低检查和跟踪栈的某些工具的性能.
这种栈检查功能对系统性能测量和调节至关重要.
因此,使用这种优化可以提高本地系统性能,但会降低全局系统性能.
为事后分析而转储栈的工具(如性能分析器)将无法工作.
调试器(例如adb、mdb、dbx)将无法转储栈或直接弹出栈帧.
最新的帧丢失帧指针之前,dtrace性能分析实用程序将无法收集栈上的任何帧的信息.
Posixpthread_cancel将无法尝试找到清除处理程序.
C++异常无法传播给C函数.
丢失了帧指针的C函数调用在C函数中引发异常的C++函数时,C++异常中会发生失败.
函数接受函数指针(例如,qsort)或全局函数(例如malloc)被干预时,通常会发生此类调用.
上面列出的后两种后果可能会影响应用程序的正常操作.
大多数应用程序代码不会遇到这些问题.
但是,使用-xO4开发的库需要详细记录客户端使用限制的文档.
注意:如果也指定了-xpg,编译器将忽略-xregs=frameptr,并发出警告.
另外,对于32位x86编译,编译器会忽略此选项,除非使用-noex选项禁用了异常.
A.
2选项参考附录AC++编译器选项315缺省值SPARC缺省值为-xregs=appl,float.
x86缺省值是包括在-fast扩展中的-xregs=no%frameptr-xregs=frameptr.
示例要使用所有可用的临时寄存器编译应用程序,请使用-xregs=appl,float.
要编译对上下文切换敏感的非浮点代码,请使用-xregs=no%appl,no%float.
另请参见SPARCV8和SPARCV9ABIA.
2.
166-xrestrict[=f](SPARC)将返回赋值指针函数参数视为限定指针.
f必须是下列值之一:表A–47-xrestrict值值含义%all整个文件中的所有指针参数均被视为限定的.
%none文件中没有指针参数被视为限定的.
%source只有在主源文件中定义的函数是限定的.
在包含文件中定义的函数不是限定的.
fn[,fn.
.
.
]用逗号隔开的一个或多个函数名称的列表.
如果指定一个函数列表,编译器会将指定函数中的指针参数视为限定指针;有关更多信息,请参阅下一节第317页中的"A.
2.
166.
1限定指针".
此命令行选项可以单独使用,但最好将其用于优化.
例如,命令:%CC-xO3-xrestrict=%allprog.
cc将文件prog.
c中的所有指针参数都视为限定指针.
命令:%CC-xO3-xrestrict=agcprog.
cc将文件prog.
c中函数agc中的所有指针参数都视为限定指针.
缺省值为%none;指定-xrestrict与指定-xrestrict=%source等效.
A.
2选项参考SunStudio12:C++用户指南316A.
2.
166.
1限定指针为使编译器高效并行执行循环,需要确定某些左值是否指定不同的存储区域.
别名是其存储区域相同的左值.
由于需要分析整个程序,因此确定对象的两个指针是否为别名是一个困难而费时的过程.
例如下面的函数vsq():示例A–3带两个指针的循环voidvsq(intn,double*a,double*b){inti;for(i=0;iintmain(){(void)printf(inastringappearsas()\n");return0;}下面是使用-xtrigraphs=yes编译该代码后的输出.
example%CC-xtrigraphs=yestrigraphs_demo.
ccexample%a.
out()inastringappearsas(]下面是使用-xtrigraphs=no编译该代码后的输出.
example%CC-xtrigraphs=notrigraphs_demo.
ccexample%a.
out()inastringappearsas()A.
2选项参考附录AC++编译器选项327另请参见有关三字母的信息,请参见《C用户指南》中关于转换到ANSI/ISOC的章节.
A.
2.
176–xunroll=n启用在可能的场合下解开循环.
该选项指定编译器是否优化(解开)循环.
A.
2.
176.
1值n为1时,建议编译器不要解开循环.
n为大于1的整数(-unroll=n)时,编译器将解开循环n次.
A.
2.
177-xustr={ascii_utf16_ushort|no}如果代码中包含要编译器转换成目标文件中UTF-16字符串的字符串文字,可以使用该选项.
如果不指定该选项,编译器既不生成、也不识别16位的字符串文字.
使用该选项时,U"ASCII_string"字符串文字会识别为无符号短整型数组.
因为这样的字符串还不属于任何标准,所以该选项的作用是使非标准C++得以识别.
不是所有文件都必须使用该选项编译.
A.
2.
177.
1值如果需要支持使用ISO10646UTF-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%catfile.
ccconstunsignedshort*foo=U"foo";constunsignedshortbar[]=U"bar";A.
2选项参考SunStudio12:C++用户指南328constunsignedshort*fun(){returnU"fun"};example%CC-xustr=ascii_utf16_ushortfile.
cc-c警告不支持十六位的字符文字.
A.
2.
178-xvector[=a]启用向量库函数调用的自动生成和/或SIMD(SingleInstructionMultipleData,单指令多数据)指令的生成.
使用此选项时,必须通过指定-fround=nearest来使用缺省的舍入模式.
a可以为下列值:表A–53-xvector标志值含义[no%]lib如果循环内的数学库调用可转换为对等效向量数学例程的单个调用,则[不]允许编译器进行此类转换.
此类转换可提高那些循环计数较大的循环的性能.
[no%]simd[不]指示编译器使用本机x86SSESIMD指令来提高某些循环的性能.
如果目标体系结构支持SIMD指令,则编译器只能接受此转换.
例如,必须指定-xarch=amd64、-xarch=amd64a或-xarch=generic64.
还必须将优化级别指定为-xO3或更高级别,而且指定-xvector=simd时还必须指定-xdepend.
yes在以后的发行版中可能会废弃此选项.
改为指定-xvector=lib.
no在以后的发行版中可能会废弃此选项.
改为指定-xvector=none.
A.
2.
178.
1缺省值缺省值为-xvector=%none.
如果指定了-xvector但未提供标志,编译器将假定-xvector=lib.
交互如果在以前没有指定-xdepend的情况下使用-xvector,-xvector将会触发-xdepend.
如果未指定优化级别或优化级别低于-x03,则-xvector选项还会将优化级别提高到-x03.
在装入步骤中,编译器包含libmvec库.
如果使用单独的命令进行编译和链接,应确保在链接CC命令中使用-xvector.
A.
2选项参考附录AC++编译器选项329A.
2.
179-xvis[={yes|no}](SPARC)要使用VISTM指令集软件开发者工具包(VISinstruction-setSoftwareDevelopersKit,VSDK)中定义的汇编语言模板时,可使用-xvis=[yes|no]命令.
VIS指令集是SPARCv9指令集的扩展.
尽管UltraSPARC是64位处理器,但在很多情况下数据都限制在8位或16位范围内,特别是多媒体应用程序中.
VIS指令可以用一条指令处理4个16位数据,这个特性使得处理诸如图像、线性代数、信号处理、音频、视频以及网络等新媒体的应用程序的性能大大提高.
A.
2.
179.
1缺省值缺省值为-xvis=no.
指定-xvis与指定-xvis=yes等效.
另请参见有关VSDK的更多信息,请访问http://www.
sun.
com/processors/vis/.
A.
2.
180–xwe通过返回非零的退出状态,将所有警告转换成错误.
A.
2.
181-Yc,path指定组件c的位置的新路径.
如果已指定组件的位置,则组件的新路径名称为path/component_name.
该选项传递给ld.
A.
2.
181.
1值c必须是下列值之一:表A–54-Y标志值含义P更改cpp的缺省目录.
0更改ccfe的缺省目录.
a更改fbe的缺省目录.
2(SPARC)更改iropt的缺省目录.
A.
2选项参考SunStudio12:C++用户指南330表A–54-Y标志(续)值含义c(SPARC)更改cg的缺省目录.
O(SPARC)更改ipo的缺省目录.
k更改CClink的缺省目录.
l更改ld的缺省目录.
f更改c++filt的缺省目录.
m更改mcs的缺省目录.
u(x86)更改ube的缺省目录.
i(x86)更改ube_ipa的缺省目录.
h(x86)更改ir2hf的缺省目录.
A指定目录以搜索所有编译器组件.
如果路径中找不到组件,搜索将转至编译器所安装的目录.
P将路径添加到缺省库搜索路径.
将在缺省库搜索路径之前搜索此路径.
S更改启动目标文件的缺省目录交互可以在命令行上指定多个-Y选项.
如果对任何一个组件应用了多个-Y选项,则保留最后一个选项.
另请参见《Solaris链接程序和库指南》A.
2.
182-z[]arg链接编辑器选项.
有关更多信息,请参见ld(1)手册页和《Solaris链接程序和库指南》.
A.
2选项参考附录AC++编译器选项331332Pragma本附录介绍了C++编译器pragma.
pragma是一个编译器指令,使用它可以向编译器提供其他信息.
该信息可以更改您所控制的编译详细信息.
例如,packpragma会影响结构内的数据布局.
编译器pragma也称为指令.
预处理程序关键字pragma是C++标准的一部分,但每个编译器中,pragma的形式、内容和含义都是不相同.
C++标准不定义任何pragma.
注–依赖于pragma的代码是不可移植的.
B.
1Pragma形式C++编译器pragma的各种形式如下所示:#pragmakeyword#pragmakeyword(a[,akeyword(a[,a#pragmasunkeyword变量keyword指特定指令;a表示参数.
B.
1.
1将函数作为pragma参数进行重载本附录中列出了几个将函数名称作为参数的pragma.
如果重载该函数,则pragma使用其前面的函数声明作为其参数.
请看以下示例:intbar(int);intfoo(int);intfoo(double);#pragmadoes_not_read_global_data(foo,bar)B附录B333在此示例中,foo指foo(double),即pragma紧前面的foo声明;而bar指bar(int),即唯一声明的bar.
现在,请看以下示例,在此示例中再次重载了foo:intfoo(int);intfoo(double);intbar(int);#pragmadoes_not_read_global_data(foo,bar)在此示例中,bar指bar(int),即唯一声明的bar.
但pragma并不知道要使用哪个版本的foo.
要更正此问题,必须将pragma放在希望pragma使用的foo定义的紧后面.
以下pragma使用本节中介绍的选择方法:does_not_read_global_datadoes_not_returndoes_not_write_global_datano_side_effectoptrarely_calledreturns_new_memoryB.
2Pragma参考本节介绍了C++编译器可识别的pragma关键字.
align使参数变量内存对齐到指定数目的字节,并覆盖缺省.
does_not_read_global_data断言函数的指定列表不直接或间接读取全局数据.
does_not_return向编译器断言,调用的指定函数不返回.
does_not_write_global_data断言函数的指定列表不直接或间接写入全局数据.
dump_macros提供关于在代码中使用宏的信息.
end_dumpmacros标记dump_macrospragma的结尾.
fini将指定函数标记为完成函数.
hdrstopB.
2Pragma参考SunStudio12:C++用户指南334标识预编译头文件的源文件活前缀的结束.
ident将指定的字符串放在可执行文件的.
comment部分.
init将指定函数标记为初始化函数.
no_side_effect表示函数不更改任何持续状态.
pack(n)控制结构偏移的布局.
n值是指定结构成员所需的最低对齐的数字(0、1、2、4或8).
rarely_called告知编译器很少调用指定的函数.
returns_new_memory断言每个命名的函数返回新分配的内存的地址,并且该指针的别名与任何其他指针的别名不同.
unknown_control_flow指定了违反程序调用的通用控制流属性的例程列表.
weak定义弱符号绑定.
B.
2.
1#pragmaalign#pragmaaligninteger(variable[,variable.
.
.
])可使用align使所列变量与integer字节内存对齐,并覆盖缺省值.
请遵循以下限制:integer必须是介于1和128之间的2的幂,有效值包括1、2、4、8、16、32、64和128.
variable是全局或静态变量,但不能是局部变量或类成员变量.
如果指定的对齐比缺省小,就使用缺省.
Pragma行必须显示在所涉及的变量的声明之前,否则该行被忽略.
在pragma行上涉及但不在下面pragma行的代码中声明的任何变量都被忽略.
以下示例中的变量是正确声明的.
#pragmaalign64(aninteger,astring,astruct)intaninteger;staticcharastring[256];structS{inta;char*b;}astruct;B.
2Pragma参考附录BPragma335#pragmaalign在名称空间内部使用时,必须使用损坏名称.
例如,以下代码中的#pragmaalign语句就是无效的.
要更正此问题,应将#pragmaalign语句中的a、b和c替换为其损坏名称.
namespacefoo{#pragmaalign8(a,b,c)staticchara;staticcharb;staticcharc;}B.
2.
2#pragmadoes_not_read_global_data#pragmadoes_not_read_global_data(funcname[,funcname])此pragma断言,指定的例程不直接或间接读取全局数据.
允许对调用这些例程的代码进行更好的优化.
具体来讲,赋值语句或存储可以围绕这样的调用移动.
指定函数的原型被声明后,该pragma才可用.
如果全局访问的断言不为真,那么程序的行为就是未定义的.
有关pragma如何将重载的函数名视为参数的更加详细的说明,请参见第333页中的"B.
1.
1将函数作为pragma参数进行重载".
B.
2.
3#pragmadoes_not_return#pragmadoes_not_return(funcname[,funcname])此pragma向编译器断言,将不会返回对指定例程的调用.
这样编译器可以执行与假定一致的优化.
例如,寄存器生命周期在调用点终止,这样可以进行进一步的优化.
如果指定的函数不返回,程序的行为就是未定义的.
指定函数的原型被声明后,该pragma才是可用的,如以下示例所示:externvoidexit(int);#pragmadoes_not_return(exit)externvoid__assert(int);#pragmadoes_not_return(__assert)有关pragma如何将重载的函数名视为参数的更加详细的说明,请参见第333页中的"B.
1.
1将函数作为pragma参数进行重载".
B.
2Pragma参考SunStudio12:C++用户指南336B.
2.
4#pragmadoes_not_write_global_data#pragmadoes_not_write_global_data(funcname[,funcname])此pragma断言,指定的一组例程不会直接或间接写入全局数据.
允许对调用这些例程的代码进行更好的优化.
具体来讲,赋值语句或存储可以围绕这样的调用移动.
指定函数的原型被声明后,该pragma才可用.
如果全局访问的断言不为真,那么程序的行为就是未定义的.
有关pragma如何将重载的函数名视为参数的更加详细的说明,请参见第333页中的"B.
1.
1将函数作为pragma参数进行重载".
B.
2.
5#pragmadumpmacros#pragmadumpmacros(value[,value.
.
.
])要查看宏在程序中如何工作时,请使用该pragma.
该pragma提供了诸如宏定义、取消定义和用法实例的信息,并按宏的处理顺序将输出打印到标准错误(stderr).
dumpmacrospragma达到文件结尾或遇到#pragmaend_dumpmacro之前一直有效.
请参见第338页中的"B.
2.
6#pragmaend_dumpmacros".
value可以是下列参数:值含义defs打印所有宏定义undefs打印所有取消定义的宏use打印关于使用的宏的信息loc另外打印defs、undefs和use的位置(路径名和行号)conds打印在条件指令中使用的宏的信息sys打印系统头文件中所有宏的定义、取消定义和使用的信息注–子选项loc、conds和sys是defs、undefs和use选项的限定符.
使用loc、conds和sys本身并不会生成任何结果.
例如,#pragmadumpmacros=loc,conds,sys不会生成什么结果.
dumpmacrospragma与命令行选项作用相同,但pragma会覆盖命令行选项.
请参见第273页中的"A.
2.
120-xdumpmacros[=value[,value.
.
.
]]".
dumpmacrospragma并不嵌套,因此以下代码行中,处理#pragmaend_dumpmacros时,将停止打印宏信息:B.
2Pragma参考附录BPragma337#pragmadumpmacros(defs,undefs)#pragmadumpmacros(defs,undefs).
.
.
#pragmaend_dumpmacrosdumpmacrospragma的作用是累积的.
以下代码行#pragmadumpmacros(defs,undefs)#pragmadumpmacros(loc)具有和以下行相同的效果#pragmadumpmacros(defs,undefs,loc)如果使用选项#pragmadumpmacros=use,no%loc,则使用的每个宏的名称仅打印一次.
如果使用选项#pragmadumpmacros=use,loc,则每次使用宏时都打印位置和宏名称.
B.
2.
6#pragmaend_dumpmacros#pragmaend_dumpmacros此pragma标记dumpmacrospragma的结尾,并停止打印有关宏的信息.
如果没有在dumpmacrospragma后面使用end_dumpmacrospragma,则dumpmacrospragma在到达文件结尾之前一直生成输出.
B.
2.
7#pragmafini#pragmafini(identifier[,identifier.
.
.
])可使用fini将identifier标记为完成函数.
此类函数应为void类型,不接受任何参数,当程序在程序控制下终止或从内存删除包含的共享对象时调用它们.
与初始化函数一样,完成函数按链接编辑器处理的顺序执行.
在源文件中,#pragmafini中指定的函数在该文件中的静态析构函数后面执行.
在pragma中使用标识符之前,请先声明这些标识符.
B.
2.
8#pragmahdrstop可将hdrstoppragma嵌入源文件的头文件中以标识源文件活前缀的结尾.
例如,考虑以下文件:example%cata.
cc#include"a.
h"#include"b.
h"B.
2Pragma参考SunStudio12:C++用户指南338#include"c.
h"#include#include"d.
h".
.
.
example%catb.
cc#include"a.
h"#include"b.
h"#include"c.
h"源文件活前缀在c.
h结束,因此需要在每个文件中的c.
h后面插入#pragmahdrstop.
#pragmahdrstop只能位于用CC命令指定的源文件活前缀的结尾处.
不要在任何include文件中指定#pragmahdrstop.
请参见第302页中的"A.
2.
155-xpch=v"和第304页中的"A.
2.
156-xpchstop=file".
B.
2.
9#pragmaident#pragmaidentstring可使用ident将string放在可执行文件的.
comment部分中.
B.
2.
10#pragmainit#pragmainit(identifier[,identifier.
.
.
])可使用init将identifier标记为初始化函数.
此类函数应为void类型,不接受任何参数,在开始执行时构造程序的内存映像的情况下调用.
执行将共享对象送入内存的操作时(程序启动时,或执行某些动态装入操作时,例如dlopen()),执行共享对象中的初始化函数.
调用到初始化函数的唯一顺序就是链接编辑器静态和动态处理该函数的顺序.
在源文件中,#pragmainit中指定的函数在该文件中的静态析构函数后面执行.
在pragma中使用标识符之前,请先声明这些标识符.
B.
2.
11#pragmano_side_effect#pragmano_side_effect(name[,name.
.
.
])可使用no_side_effect指示函数不更改任何持久状态.
Pragma声明了命名的函数不具有任何副作用.
这意味着函数将返回仅依赖于传递参数的结果.
此外,函数和后面的函数调用:B.
2Pragma参考附录BPragma339不读取或写入调用点的调用者中可视的程序状态的任何部分.
不执行I/O.
不更改调用点不可视程序状态的任何部分.
编译器执行优化时可以使用该信息.
如果函数具有副作用,执行调用该函数的程序的结果是未定义的.
name参数指定当前转换单元中函数的名称.
Pragma必须与函数在相同的作用域,并且必须在函数声明之后出现.
pragma必须在函数定义之前.
有关pragma如何将重载的函数名视为参数的更加详细的说明,请参见第333页中的"B.
1.
1将函数作为pragma参数进行重载".
B.
2.
12#pragmaopt#pragmaoptlevel(funcname[,funcname])funcname指定当前转换单元中定义的函数的名称.
level值指定用于所指定函数的优化级别.
可以指定优化级别0、1、2、3、4、5.
可以通过将level设置为0来关闭优化.
必须在pragma之前使用原型或空参数列表声明函数.
pragma则必须对要优化的函数进行定义.
pragma中所列任何函数的优化级别都降为-xmaxopt值.
-xmaxopt=off时,忽略pragma.
有关pragma如何将重载的函数名视为参数的更加详细的说明,请参见第333页中的"B.
1.
1将函数作为pragma参数进行重载".
B.
2.
13#pragmapack(n)#pragmapack([n])可使用pack影响对结构成员的封装.
如果使用了该关键字,则n必须为0或2的幂.
0以外的值指示编译器为数据类型使用n字节对齐和平台的自然对齐中的较小者.
例如,以下指令使在指令后面(以及后续的pack指令前面)定义的所有结构成员对齐时依据的字节边界不严于2字节边界,即使正常对齐是4或8字节边界也是如此.
#pragmapack(2)n为0或省略该项时,成员对齐还原为自然对齐值.
如果n值等于或大于平台上最严格的对齐时,则采用自然对齐.
下表显示了每个平台最严格的对齐.
B.
2Pragma参考SunStudio12:C++用户指南340表B–1平台上最严格的对齐平台最严格的对齐x864SPARC通用、V8、V8a、V8plus、V8plusa、V8plusb8SPARCV9、V9a、V9b16pack指令应用于自身与下一个pack指令之间的所有结构定义.
如果在具有不同包装的不同转换单元中定义了相同的结构,那么程序会因某种原因而失败.
具体来说,不应该在包括定义预编译库接口的头文件之前使用pack指令.
建议将pack指令放在要封装的结构紧前面的程序代码中,并将#pragmapack()放在该结构紧后面.
如果在SPARC平台上使用#pragmapack封装效果比类型的缺省对齐紧密,必须为应用程序的编译和链接指定-misalign选项.
下表显示了整型数据类型的存储大小和缺省对齐.
表B–2存储大小和缺省对齐字节数类型SPARCV8大小,对齐SPARCV9大小,对齐x86大小,对齐bool1,11,11,1char1,11,11,1short2,22,22,2wchar_t4,44,44,4int4,44,44,4long4,48,84,4浮点4,44,44,4双精度8,88,88,4长双精度16,816,1612,4指向数据的指针4,48,84,4指向函数的指针4,48,84,4指向成员数据的指针4,48,84,4指向成员函数的指针8,416,88,4B.
2Pragma参考附录BPragma341B.
2.
14#pragmararely_called#pragmsrarely_called(funcname[,funcname])此pragma提示编译器,很少调用指定函数.
这样,编译器可以在此类例程的调用点执行配置文件反馈样式的优化,而没有配置文件收集阶段的开销.
因为该pragma只是建议,所以编译器不执行基于该pragma的任何优化.
只有在声明指定函数的原型之后,才能使用#pragmararely_called预处理程序指令.
以下是#pragmararely_called示例:externvoiderror(char*message);#pragmararely_called(error)有关pragma如何将重载的函数名视为参数的更加详细的说明,请参见第333页中的"B.
1.
1将函数作为pragma参数进行重载".
B.
2.
15#pragmareturns_new_memory#pragmareturns_new_memory(name[,name.
.
.
])此pragma断言,每个指定的函数都返回新分配内存的地址,以及指针没有与任何其他指针相关的别名.
该信息允许优化器更好地跟踪指针值并明确内存位置.
这样可以改善调度和管线操作.
如果该断言为假,那么执行调用该函数的程序的结果是未定义的.
name参数指定当前转换单元中函数的名称.
Pragma必须与函数在相同的作用域,并且必须在函数声明之后出现.
pragma必须在函数定义之前.
有关pragma如何将重载的函数名视为参数的更加详细的说明,请参见第333页中的"B.
1.
1将函数作为pragma参数进行重载".
B.
2.
16#pragmaunknown_control_flow#pragmaunknown_control_flow(name[,name.
.
.
])可使用unknown_control_flow指定一组违反过程调用的常规控制流属性的例程.
例如,可通过任意的任何其他例程调用来访问setjmp()调用后面的语句.
该语句通过调用longjmp()来访问.
因为这种例程使标准流程图分析无效,调用它们的例程不能安全地优化,所以要禁用优化器来编译这些例程.
如果函数名称被重载,那么会选择最近声明的函数.
B.
2Pragma参考SunStudio12:C++用户指南342B.
2.
17#pragmaweak#pragmaweakname1[=name2]可使用weak定义弱全局符号.
该pragma主要在源文件中用于生成库.
链接程序在不能解决弱符号时不会发出警告.
weakpragma可以按以下两种形式之一来指定符号:字符串形式.
字符串必须是C++变量或函数的损坏名称.
无效损坏名称引用的行为是不可预测的.
后端可以或不可以产生无效损坏名称引用的错误.
无论是否产生错误,使用无效损坏名称时后端的行为都是不可预测的.
标识符形式.
标识符必须是在编译单元中以前声明的C++函数的明确标识符.
标识符形式不能用于变量.
前端(ccfe)遇到无效的标识符引用时会生成错误消息.
B.
2.
17.
1#pragmaweakname采用#pragmaweakname形式时,指令使name成为弱符号.
链接程序没有找到name的符号定义时,不会显示错误消息,也不会出现符号的多个弱定义的错误消息.
链接程序仅执行第一个遇到的定义.
如果另一个编译单元有函数或变量的强定义,那么name将链接到它.
如果没有name的强定义,那么链接程序符号的值为0.
以下指令将ping定义为弱符号.
链接程序找不到名为ping的符号的定义时,不会生成错误消息.
#pragmaweakping#pragmaweakname1=name2采用#pragmaweakname1=name2形式时,符号name1成为对name2的弱引用.
如果没有在其他地方定义name1,那么name1的值为name2.
如果在其他地方定义了name1,那么链接程序使用该定义并忽略对name2的弱引用.
以下指令指示链接程序解析对bar(如果已在程序中某处定义)的任何引用,以及解析对foo的引用.
#pragmaweakbar=foo采用标识符形式时,必须在当前编译单元中声明和定义name2.
例如:externvoidbar(int){.
.
.
}externvoid_bar(int);#pragmaweak_bar=bar使用字符串形式时,符号不需要预先声明.
如果以下示例中的_bar和bar都是extern"C",则不需要声明函数.
但bar必须在同一对象中定义.
B.
2Pragma参考附录BPragma343extern"C"voidbar(int){.
.
.
}#pragmaweak"_bar"="bar"重载函数使用标识符形式时,必须在pragma位置的作用域中正好有一个具有指定名称的函数.
尝试将标识符形式#pragmaweak用于重载函数会出现错误.
例如:intbar(int);floatbar(float);#pragmaweakbar//error,ambiguousfunctionname要避免错误,请使用字符串形式,如以下示例所示.
intbar(int);floatbar(float);#pragmaweak"__1cDbar6Fi_i_"//makefloatbar(int)weak有关更多信息,请参见Solaris《链接程序和库指南》.
B.
2Pragma参考SunStudio12:C++用户指南344词汇表ABI请参见ApplicationBinaryInterface(应用程序二进制接口).
abstractclass(抽象类)包含一个或多个抽象方法并因此不能被实例化的类.
定义抽象类的目的是为了通过实现抽象方法,使其他类可以扩展抽象类并使其固定.
abstractmethod(抽象方法)不包含实现的方法.
ANSIC美国国家标准学会定义的C编程语言.
ANSIC与ISO定义相同.
请参见ISO.
ANSI/ISOC++美国国家标准学会和ISOC++编程语言标准.
请参见ISO.
applicationbinaryinterface(应用程序二进制接口)编译的应用程序和运行应用程序的操作系统之间的二进制系统接口.
array(数组)内存中连续存储一组单一数据类型值的数据结构.
每个值可以按在数组中的位置访问.
baseclass(基类)请参见inheritance(继承).
binarycompatibility(二进制兼容性)链接目标文件的能力,目标文件由某一个发行版本编译,而使用另一个不同发行版本的编译器.
binding(绑定)将函数调用与特定函数定义关联.
更一般的说来,将名称与特定的实体关联.
cfrontC++到C的编译器程序,可以将C++转换为C源代码,然后用标准C编译器编译.
classtemplate(类模板)描述一组类或相关数据类型的模板.
classvariable(类变量)作为一个整体与特定类关联但与类的特定实例不关联的数据项.
类变量在类定义中定义.
类变量也称为静态字段.
另请参见instancevariable(实例变量).
class(类)由命名的数据元素(可以是不同类型的数据元素)和可以和数据一起执行的一组操作组成的用户定义数据类型.
compileroption(编译器选项)更改编译器行为的指令.
例如,-g选项表示通知编译器为调试器生成数据.
同义字:标志、开关.
constructor(构造函数)每当创建类对象时编译器都会自动调用的特殊类成员函数,用于确保初始化相应对象的实例变量.
构造函数必须始终具有与该函数所属的类相同的名称.
请参见destructor(析构函数).
345datamember(数据成员)是数据而不是函数或类型定义的类元素.
datatype(数据类型)允许表示诸如字符、整数或浮点数等的机制.
类型决定了分配到变量的存储以及能在变量上执行的操作.
derivedclass(派生类)请参见inheritance(继承).
destructor(析构函数)每当销毁类对象或对类指针应用运算符delete时编译器都会自动调用的特殊类成员函数.
析构函数必须始终具有与该函数所属的类相同的名称,该类前有一个(~).
请参见constructor(构造函数).
dynamicbinding(动态绑定)在运行时函数调用到函数体的连接.
有虚函数时才需动态绑定.
也称为迟绑定、运行时绑定.
dynamiccast(动态强制类型转换)将指针或引用从声明的类型转换到与引用到的动态类型一致的任何类型的安全方法.
dynamictype(动态类型)由具有不同声明类型的指针或引用访问的对象的实际类型.
earlybinding(早绑定)请参见staticbinding(静态绑定).
ELFfile(ELF文件)编译器生成的可执行和链接格式文件.
exceptionhandler(异常处理程序)用于处理错误而专门编写的代码,以及异常发生时为已注册的处理程序自动调用的代码.
exceptionhandling(异常处理)设计用于截取并防止错误的错误恢复过程.
在程序执行期间,如果检测到同步错误,那么程序的控制返回到在执行初期注册的异常处理程序,并且忽略包含错误的代码.
exception(异常)在正常的程序流中出现的错误,阻止程序继续运行.
某些错误的原因包括了内存枯竭或被零除.
flag(标志)请参见compileroption(编译器选项).
functionoverloading(函数重载)将相同的名称但不同的参数类型和数字赋予不同的函数.
也称为函数多态.
functionprototype(函数原型)描述函数与程序其他部分之间的接口的声明.
functiontemplate(函数模板)允许编写可以稍后用作模型或模式的单一函数(用于编写相关函数)的机制.
functionalpolymorphism(函数多态)请参见functionoverloading(函数重载).
idempotent(幂等)头文件属性,在一个转换单元中包括多次与包括一次具有相同效果.
incrementallinker(增量链接程序)通过仅将更改后的.
o文件链接到前一个可执行文件来创建新的可执行文件的链接程序.
datamember(数据成员)SunStudio12:C++用户指南346inheritance(继承)面向对象编程的一个功能,使得程序员可以从现有类(基类)派生新的类(派生类).
有以下三种继承:公共的、受保护的和专用的.
inlinefunction(内联函数)用实际函数代码替换函数调用的函数.
instancevariable(实例变量)与特定对象关联的任何数据项.
类的每个实例具有在类中定义的实例变量的自身副本.
实例变量也称为字段.
另请参见classvariable(类变量).
instantiation(实例化)C++编译器从模板创建可用的函数或对象的过程.
ISO国际标准化组织.
K&RCBrianKernighan和DennisRitchie在ANSIC之前开发的实际上的C编程语言标准.
keyword(关键字)在编程语言中具有唯一含义,并且仅在该语言的专用上下文中使用的字.
latebinding(迟绑定)请参见dynamicbinding(动态绑定).
linker(链接程序)连接目标代码和库以形成完整的可执行程序的工具.
localvariable(局部变量)在块内已知的数据项,但块外代码不可访问.
例如,在方法内定义的任何变量都是局部变量,在方法外部无法使用.
locale(语言环境)地理位置和/或语言唯一的一组约定,例如日期、时间和货币格式.
lvalue(左值)指定变量数据值在内存中的存储位置的表达式.
即显示在赋值运算符左侧的变量实例.
mangle(损坏)请参见namemangling(名称损坏).
memberfunction(成员函数)是函数而非数据定义或类型定义的类元素.
method(方法)在某些面向对象的语言中,成员函数的另外一个名称.
multipleinheritance(多继承)直接源于多个基类的派生类的继承.
multithreading(多线程)在单处理器或多处理器系统上开发并行应用程序的软件技术.
namemangling(名称损坏)在C++中,大量函数可以共享相同的名称,因此仅用名称并不能很好的区分不同的函数.
编译器通过名称损坏解决这个问题-为函数创建由函数名称及其参数的某些组合组成的唯一名称-从而实现类型安全的链接.
也称为名称修饰.
namespace(名称空间)控制全局名称的作用域的机制,做法是允许全局空间划分为独立的唯一命名的作用域.
operatoroverloading(运算符重载)使用同一运算符表示法产生不同结果的能力.
函数重载的特殊形式.
optimization(优化)改善编译器生成的目标代码执行效率的过程.
option(选项)请参见compileroption(编译器选项).
overloading(重载)将相同的名称赋予多个函数或运算符.
overloading(重载)347polymorphism(多态性)引用到对象的指针或引用的动态类型与声明的指针或引用类型不同的能力.
pragma指示编译器执行特定操作的编译器预处理程序指令或特殊的注释.
runtimebinding(运行时绑定)请参见dynamicbinding(动态绑定).
runtimetypeidentification(运行时类型标识)提供标准方法以让程序在运行时决定对象类型的机制.
rvalue(右值)位于赋值运算符右侧的变量.
右值可以读取而不能被更改.
scope(作用域)操作或定义应用的范围.
stab在目标代码中生成的符号表条目.
在a.
out文件和ELF文件中使用相同的格式来包含调试信息.
stack(栈)数据存储方法,通过该方法数据可以增加到栈顶部或从栈顶部删除数据,采用的是后进先出策略.
staticbinding(静态绑定)在编译期间函数调用到函数体的连接.
也称为earlybinding(早绑定).
subroutine(子例程)函数.
在Fortran中,子例程是不返回值的函数.
switch(开关)请参见compileroption(编译器选项).
symboltable(符号表)程序编译时显示的所有标识符、程序中标识符的位置和属性的列表.
编译器使用该表来解释标识符的使用.
symbol(符号)表示某些程序实体的名称或标签.
templatedatabase(模板数据库)包含需要处理并实例化模板(程序需要)的所有配置文件的目录.
templateoptionsfile(模板选项文件)由用户提供的文件,其中包含模板编译选项、源码位置和其他信息.
模板选项文件现在已过时,不应该使用.
templatespecialization(模板专门化)类模板成员函数的专用实例,用于缺省不能处理给出的足够类型时覆盖缺省实例.
819云互联是海外领先的互联网业务平台服务提供商。专注为用户提供低价高性能云计算产品,致力于云计算应用的易用性开发,并引导云计算在国内普及。目前平台研发以及运营云服务基础设施服务平台(IaaS),面向全球客户提供基于云计算的IT解决方案与客户服务,拥有丰富的海外资源、香港,日本,美国等各国优质的IDC资源。官方网站:https://www.819yun.com香港特价物理服务器:地区CPU内存带宽...
RackNerd 商家我们应该是比较熟悉的商家,速度一般,但是人家便宜且可选机房也是比较多的,较多集中在美国机房。包括前面的新年元旦促销的时候有提供年付10美元左右的方案,实际上RackNerd商家的营销策略也是如此,每逢节日都有活动,配置简单变化,价格基本差不多,所以我们网友看到没有必要囤货,有需要就选择。RackNerd 商家这次2022农历新年也是有几款年付套餐。低至RackNerd VPS...
Hostodo是一家成立于2014年的国外VPS主机商,现在主要提供基于KVM架构的VPS主机,美国三个地区机房:拉斯维加斯、迈阿密和斯波坎,采用NVMe或者SSD磁盘,支持支付宝、PayPal、加密货币等付款方式。商家最近对于上架不久的斯波坎机房SSD硬盘VPS主机提供66折优惠码,适用于1GB或者以上内存套餐年付,最低每年12美元起。下面列出几款套餐配置信息。CPU:1core内存:256MB...