SunMicrosystems,Inc.
www.
sun.
com请将有关本文档的意见和建议提交至:http://www.
sun.
com/hwdocs/feedbackC++用户指南SunStudio11文件号码819-4815-102005年1月,修订版A版权所有2005SunMicrosystems,Inc.
,4150NetworkCircle,SantaClara,California95054,U.
S.
A.
保留所有权利.
美国政府权利-商业用途.
政府用户应遵循SunMicrosystems,Inc.
的标准许可协议,以及FAR(FederalAcquisitionRegulations,即"联邦政府采购法规")的适用条款及其补充条款.
必须依据许可证条款使用.
本发行版可能包含由第三方开发的内容.
本产品的某些部分可能是从BerkeleyBSD系统衍生出来的,并获得了加利福尼亚大学的许可.
UNIX是X/OpenCompany,Ltd.
在美国和其他国家/地区独家许可的注册商标.
Sun、SunMicrosystems、Sun徽标、Java和JavaHelp是SunMicrosystems,Inc.
在美国和其他国家/地区的商标或注册商标.
所有的SPARC商标的使用均已获得许可,它们是SPARCInternational,Inc.
在美国和其他国家/地区的商标或注册商标.
标有SPARC商标的产品均基于由SunMicrosystems,Inc.
开发的体系结构.
本服务手册所介绍的产品以及所包含的信息受美国出口控制法制约,并应遵守其他国家/地区的进出口法律.
严禁将本产品直接或间接地用于核设施、导弹、生化武器或海上核设施,也不能直接或间接地出口给核设施、导弹、生化武器或海上核设施的最终用户.
严禁出口或转口到美国禁运的国家/地区以及美国禁止出口清单中所包含的实体,包括但不限于被禁止的个人以及特别指定的国家/地区的公民.
本文档按"原样"提供,对于所有明示或默示的条件、陈述和担保,包括对适销性、适用性或非侵权性的默示保证,均不承担任何责任,除非此免责声明的适用范围在法律上无效.
iii目录阅读本书之前xxvii本书的结构xxvii印刷约定xxviiiShell提示符xxix支持的平台xxix访问SunStudio软件和手册页xxix访问SunStudio文档xxxii访问相关的Solaris文档xxxiv访问相关的C++手册页xxxiv其他公司出版的书籍xxxv开发者资源xxxv联系Sun技术支持xxxviSun欢迎您提出意见xxxvi第I部分C++编译器1.
C++编译器1–11.
1SunStudio10C++5.
8编译器的新特性和新功能1–11.
2SunStudio10C++5.
7编译器的新特性和新功能1–31.
3标准一致性1–51.
4C++自述文件1–5iv《C++用户指南》2005年11月1.
5手册页1–61.
6C++实用程序1–61.
7本地语言支持1–62.
使用C++编译器2–12.
1入门2–12.
2调用编译器2–22.
2.
1命令语法2–32.
2.
2文件名称约定2–32.
2.
3使用多个源文件2–42.
3使用不同编译器版本进行编译2–42.
4编译和链接2–52.
4.
1编译和链接序列2–52.
4.
2分别编译和链接2–62.
4.
3一致编译和链接2–62.
4.
4为SPARCV9编译2–72.
4.
5诊断编译器2–72.
4.
6了解编译器的组织2–82.
5预处理指令和名称2–92.
5.
1Pragma2–92.
5.
2具有可变数量参数的宏2–92.
5.
3预定义的名称2–102.
5.
4#error2–102.
6内存要求2–102.
6.
1交换空间大小2–102.
6.
2增加交换空间2–112.
6.
3虚拟内存的控制2–112.
6.
4内存要求2–122.
7简化命令2–12目录v2.
7.
1在CShell中使用别名2–122.
7.
2使用CCFLAGS来指定编译选项2–132.
7.
3使用make2–133.
使用C++参阅编译器选项3–13.
1语法3–13.
2通用指南3–13.
3按功能汇总的选项3–23.
3.
1代码生成选项3–23.
3.
2编译时性能选项3–33.
3.
3调试选项3–33.
3.
4浮点选项3–43.
3.
5语言选项3–53.
3.
6库选项3–53.
3.
7许可证选项3–63.
3.
8废弃的选项3–73.
3.
9输出选项3–73.
3.
10运行时性能选项3–83.
3.
11预处理程序选项3–103.
3.
12文件配置选项3–103.
3.
13参考选项3–113.
3.
14源文件选项3–113.
3.
15模板选项3–113.
3.
16线程选项3–12第II部分编写C++程序4.
语言扩展参阅4–14.
1链接程序作用域4–14.
2线程局部存储4–2vi《C++用户指南》2005年11月4.
3用限制较少的虚函数覆盖4–34.
4生成enum类型和变量的向前声明4–34.
5使用不完整enum类型4–44.
6将enum名称作为作用域限定符4–44.
7使用匿名struct声明4–54.
8传递匿名类实例的地址4–64.
9将静态名称空间作用域函数声明为类友元4–74.
10使用函数名称的预定义__func__符号4–75.
程序组织5–15.
1头文件5–15.
1.
1可适应语言的头文件5–15.
1.
2幂等头文件5–25.
2模板定义5–35.
2.
1包括的模板定义5–35.
2.
2独立的模板定义5–46.
创建和使用模板6–16.
1函数模板6–16.
1.
1函数模板声明6–16.
1.
2函数模板定义6–26.
1.
3函数模板用法6–26.
2类模板6–26.
2.
1类模板声明6–36.
2.
2类模板定义6–36.
2.
3类模板成员定义6–46.
2.
4类模板的用法6–56.
3模板实例化6–56.
3.
1隐式模板实例化6–5目录vii6.
3.
2显式模板实例化6–66.
4模板组合6–76.
5默认模板参数6–86.
6模板专门化6–86.
6.
1模板专门化声明6–86.
6.
2模板专门化定义6–96.
6.
3模板专门化使用和实例化6–96.
6.
4部分专门化6–96.
7模板问题部分6–106.
7.
1非本地名称解析和实例化6–106.
7.
2作为模板参数的本地类型6–116.
7.
3模板函数的友元声明6–126.
7.
4在模板定义内使用限定名称6–146.
7.
5嵌套模板名称6–146.
7.
6引用静态变量和静态函数6–156.
7.
7在同一目录中使用模板生成多个程序6–157.
编译模板7–17.
1冗余编译7–17.
2系统信息库管理7–17.
2.
1生成的实例7–17.
2.
2整个类实例化7–27.
2.
3编译时实例化7–27.
2.
4模板实例的放置和链接7–27.
3外部实例7–37.
3.
1静态实例7–47.
3.
2全局实例7–47.
3.
3显式实例7–57.
3.
4半显式实例7–5viii《C++用户指南》2005年11月7.
4模板系统信息库7–57.
4.
1系统信息库结构7–57.
4.
2写入模板系统信息库7–67.
4.
3从多模板系统信息库读取7–67.
4.
4共享模板系统信息库7–67.
4.
5模板实例自动与-instances=extern一致7–67.
5模板定义搜索7–77.
5.
1源文件位置约定7–77.
5.
2定义搜索路径7–77.
5.
3诊断有问题的搜索7–78.
异常处理8–18.
1同步和异步异常8–18.
2指定运行时错误8–18.
3禁用异常8–28.
4使用运行时函数和预定义的异常8–38.
5将异常与信号和Setjmp/Longjmp混合8–48.
6生成具有异常的共享库8–49.
类型转换操作9–19.
1const_cast9–29.
2reinterpret_cast9–29.
3static_cast9–39.
4动态类型转换9–49.
4.
1将分层结构向上类型转换9–49.
4.
2类型转换到void*9–49.
4.
3将分层结构向下或交叉类型转换9–410.
改善程序性能10–110.
1避免临时对象10–1目录ix10.
2使用内联函数10–210.
3使用默认运算符10–210.
4使用值类10–310.
4.
1选择直接传递类10–310.
4.
2在不同的处理器上直接传递类10–410.
5缓存成员变量10–411.
生成多线程程序11–111.
1生成多线程程序11–111.
1.
1表明多线程编译11–211.
1.
2与线程和信号一起使用C++支持库11–211.
2在多线程程序中使用异常11–211.
2.
1线程取消11–211.
3在线程之间共享C++标准库对象11–311.
4在多线程环境中使用传统iostream11–511.
4.
1多线程安全的iostream库的组织11–611.
4.
2对iostream库进行接口更改11–1111.
4.
3全局和静态数据11–1411.
4.
4序列执行11–1411.
4.
5对象锁定11–1511.
4.
6多线程安全类11–1611.
4.
7对象析构11–1711.
4.
8示例应用程序11–18第III部分库12.
使用库12–112.
1C库12–112.
2C++编译器提供的库12–112.
2.
1C++库描述12–2x《C++用户指南》2005年11月12.
2.
2访问C++库的手册页12–312.
2.
3默认C++库12–412.
3相关的库选项12–412.
4使用类库12–612.
4.
1iostream库12–612.
4.
2complex库12–712.
4.
3链接C++库12–912.
5静态链接标准库12–912.
6使用共享库12–1012.
7替换C++标准库12–1112.
7.
1可以替换的内容12–1212.
7.
2不可以替换的内容12–1212.
7.
3安装替换库12–1212.
7.
4使用替换库12–1212.
7.
5标准头文件实现12–1313.
使用C++标准库13–113.
1C++标准库头文件13–213.
2C++标准库手册页13–313.
3STLport13–1313.
3.
1重新分发和支持的STLport库13–1414.
使用传统iostream库14–114.
1预定义的iostream14–114.
2iostream交互的基本结构14–214.
3使用传统iostream库14–314.
3.
1使用iostream进行输出14–314.
3.
2使用iostream进行输入14–614.
3.
3定义自己的提取运算符14–7目录xi14.
3.
4使用char*提取器14–714.
3.
5读取任何单一字符14–814.
3.
6二进制输入14–814.
3.
7查看输入14–914.
3.
8提取空白14–914.
3.
9处理输入错误14–914.
3.
10使用具有stdio的iostream14–1014.
4创建iostream14–1114.
4.
1处理使用类fstream的文件14–1114.
5iostream的赋值14–1414.
6格式控制14–1414.
7控制器14–1514.
7.
1使用无格式控制器14–1614.
7.
2参数化控制器14–1714.
8Strstream:数组的iostream14–1814.
9Stdiobuf:stdio文件的iostream14–1914.
10Streambuf14–1914.
10.
1和Streambuf一起使用14–1914.
10.
2使用Streambuf14–2014.
11iostream手册页14–2014.
12iostream术语14–2215.
使用复数运算库15–115.
1复数库15–115.
1.
1使用复数库15–215.
2类型complex15–215.
2.
1类complex的构造函数15–215.
2.
2算法运算符15–315.
3数学函数15–4xii《C++用户指南》2005年11月15.
4错误处理15–515.
5输入和输出15–615.
6混合模式运算15–715.
7效率15–715.
8复数手册页15–816.
生成库16–116.
1了解库16–116.
2生成静态(归档)库16–216.
3生成动态(共享)库16–216.
4生成包含异常的共享库16–316.
5生成专用的库16–416.
6生成公用的库16–416.
7生成具有CAPI的库16–416.
8使用dlopen从C程序访问C++库16–5第IV部分附录A.
C++编译器选项A–1A.
1选项信息的结构A–2A.
2选项参考A–2A.
2.
1-386A–2A.
2.
2-486A–3A.
2.
3-aA–3A.
2.
4-BbindingA–3A.
2.
5-cA–4A.
2.
6-cg{89|92}A–5A.
2.
7-compat[={4|5}]A–5A.
2.
8+dA–7A.
2.
9-D[]name[=def]A–8目录xiiiA.
2.
10-d{y|n}A–9A.
2.
11-dalignA–10A.
2.
12-dryrunA–11A.
2.
13-EA–11A.
2.
14+e{0|1}A–12A.
2.
15-erroff[=t]A–12A.
2.
16-errtags[=a]A–13A.
2.
17-errwarn[=t]A–14A.
2.
18-fastA–15A.
2.
19-features=a[,a.
.
.
]A–17A.
2.
20-filt[=filter[,filter.
.
.
]]A–21A.
2.
21-flagsA–24A.
2.
22-fnonstdA–24A.
2.
23-fns[={yes|no}]A–24A.
2.
24-fprecision=pA–26A.
2.
25-fround=rA–27A.
2.
26-fsimple[=n]A–28A.
2.
27-fstoreA–29A.
2.
28-ftrap=t[,t.
.
.
]A–29A.
2.
29-GA–31A.
2.
30-gA–32A.
2.
31-g0A–33A.
2.
32-HA–33A.
2.
33-h[]nameA–33A.
2.
34-helpA–34A.
2.
35-IpathnameA–34A.
2.
36-I-A–35A.
2.
37-iA–37xiv《C++用户指南》2005年11月A.
2.
38-inlineA–37A.
2.
39-instances=aA–37A.
2.
40-instlib=filenameA–38A.
2.
41-KPICA–39A.
2.
42-KPICA–40A.
2.
43-keeptmpA–40A.
2.
44-LpathA–40A.
2.
45-llibA–40A.
2.
46-libmieeeA–41A.
2.
47-libmilA–41A.
2.
48-library=l[,l.
.
.
]A–41A.
2.
49-mcA–45A.
2.
50-migrationA–45A.
2.
51-misalignA–46A.
2.
52-mr[,string]A–46A.
2.
53-mtA–47A.
2.
54-nativeA–47A.
2.
55-noexA–47A.
2.
56-nofstoreA–48A.
2.
57-nolibA–48A.
2.
58-nolibmilA–48A.
2.
59-noqueueA–48A.
2.
60-norunpathA–48A.
2.
61-OA–49A.
2.
62-OlevelA–49A.
2.
63-ofilenameA–49A.
2.
64+pA–50A.
2.
65-PA–50目录xvA.
2.
66-pA–50A.
2.
67-pentiumA–51A.
2.
68-pgA–51A.
2.
69-PICA–51A.
2.
70-picA–51A.
2.
71-ptaA–51A.
2.
72-ptipathA–51A.
2.
73-ptoA–52A.
2.
74-ptrA–52A.
2.
75-ptvA–52A.
2.
76-Qoptionphaseoption[,option.
.
.
A–52A.
2.
77-qoptionphaseoptionA–54A.
2.
78-qpA–54A.
2.
79-QproducesourcetypeA–54A.
2.
80-qproducesourcetypeA–54A.
2.
81-Rpathname[:pathname.
.
.
A–54A.
2.
82-readmeA–55A.
2.
83-SA–55A.
2.
84-sA–55A.
2.
85-sbA–56A.
2.
86-sbfastA–56A.
2.
87-staticlib=l[,l…]A–56A.
2.
88-sync_stdio=[yes|no]A–58A.
2.
89-temp=pathA–59A.
2.
90-template=opt[,opt.
.
.
A–59A.
2.
91-timeA–61A.
2.
92-UnameA–61A.
2.
93-unroll=nA–62xvi《C++用户指南》2005年11月A.
2.
94-VA–62A.
2.
95-vA–62A.
2.
96-vdelxA–62A.
2.
97-verbose=v[,v_]A–63A.
2.
98+wA–64A.
2.
99+w2A–64A.
2.
100-wA–65A.
2.
101-XmA–65A.
2.
102-xaA–65A.
2.
103-xalias_level[=n]A–66A.
2.
104-xarA–68A.
2.
105-xarch=isaA–69A.
2.
106-xautoparA–74A.
2.
107-xbinopt={prepare|off}A–75A.
2.
108-xbuiltin[={%all|%none}]A–76A.
2.
109-xcache=cA–77A.
2.
110-xcg[89|92]A–78A.
2.
111-xchar[=o]A–78A.
2.
112-xcheck[=i]A–80A.
2.
113-xchip=cA–80A.
2.
114-xcode=aA–82A.
2.
115-xcrossfile[=n]A–84A.
2.
116-xdebugformat=[stabs|dwarf]A–85A.
2.
117-xdepend=[yes|no]A–86A.
2.
118-xdumpmacros[=value[,value.
.
.
]]A–86A.
2.
119-xeA–90A.
2.
120-xF[=v[,v.
.
.
]]A–90A.
2.
121-xhelp=flagsA–91目录xviiA.
2.
122-xhelp=readmeA–91A.
2.
123-xiaA–92A.
2.
124-xinline[=func_spec[,func_spec.
.
.
]]A–92A.
2.
125-xipo[={0|1|2}]A–94A.
2.
126-xjobs=nA–97A.
2.
127-xlang=language[,language]A–97A.
2.
128-xldscope={v}A–99A.
2.
129-xlibmieeeA–100A.
2.
130-xlibmilA–100A.
2.
131-xlibmoptA–101A.
2.
132-xlic_lib=sunperfA–101A.
2.
133-xlicinfoA–101A.
2.
134-xlinkopt[=level]A–101A.
2.
135-xMA–103A.
2.
136-xM1A–104A.
2.
137-xMergeA–104A.
2.
138-xmaxopt[=v]A–104A.
2.
139-xmemalign=abA–104A.
2.
140-xmodel=[a]A–106A.
2.
141-xnativeconnect[=i]A–106A.
2.
142-xnolibA–108A.
2.
143-xnolibmilA–110A.
2.
144-xnolibmoptA–110A.
2.
145-xOlevelA–110A.
2.
146-xopenmp[=i]A–113A.
2.
147-xpagesize=nA–114A.
2.
148-xpagesize_heap=nA–115A.
2.
149-xpagesize_stack=nA–116xviii《C++用户指南》2005年11月A.
2.
150-xpch=vA–116A.
2.
151-xpchstop=fileA–119A.
2.
152-xpgA–120A.
2.
153-xport64[=(v)]A–120A.
2.
154-xprefetch[=a[,a.
.
.
]]A–125A.
2.
155-xprefetch_auto_type=aA–127A.
2.
156-xprefetch_level[=i]A–127A.
2.
157-xprofile=pA–128A.
2.
158-xprofile_ircache[=path]A–130A.
2.
159-xprofile_pathmapA–131A.
2.
160-xregs=r[,r.
.
.
]A–131A.
2.
161-xrestrict[=f]A–133A.
2.
162-xsA–135A.
2.
163-xsafe=memA–135A.
2.
164-xsbA–135A.
2.
165-xsbfastA–135A.
2.
166-xspaceA–136A.
2.
167-xtarget=tA–136A.
2.
168-xthreadvar[=o]A–143A.
2.
169-xtimeA–144A.
2.
170-xtrigraphs[={yes|no}]A–144A.
2.
171-xunroll=nA–145A.
2.
172-xustr={ascii_utf16_ushort|no}A–146A.
2.
173-xvector[=a]A–147A.
2.
174-xvis[={yes|no}]A–147A.
2.
175-xweA–148A.
2.
176-Yc,pathA–148A.
2.
177-z[]argA–149目录xixB.
PragmaB–1B.
1Pragma形式B–1B.
1.
1将函数作为Pragma参数进行重载B–2B.
2Pragma引用B–2B.
2.
1#pragmaalignB–4B.
2.
2#pragmadoes_not_read_global_dataB–4B.
2.
3#pragmadoes_not_returnB–5B.
2.
4#pragmadoes_not_write_global_dataB–5B.
2.
5#pragmadumpmacrosB–6B.
2.
6#pragmaend_dumpmacrosB–7B.
2.
7#pragmafiniB–7B.
2.
8#pragmahdrstopB–8B.
2.
9#pragmaidentB–8B.
2.
10#pragmainitB–8B.
2.
11#pragmano_side_effectB–9B.
2.
12#pragmaoptB–9B.
2.
13#pragmapack(n)B–10B.
2.
14#pragmararely_calledB–11B.
2.
15#pragmareturns_new_memoryB–12B.
2.
16#pragmaunknown_control_flowB–12B.
2.
17#pragmaweakB–13术语表术语表–1索引索引–1xx《C++用户指南》2005年11月xxi表表P-1字体约定xxviii表P-2代码约定xxviii表2-1C++编译器识别的文件名称后缀3表2-2C++编译系统的组件8表3-1选项语法格式示例1表3-2代码生成选项2表3-3编译时性能选项3表3-4调试选项3表3-5浮点选项4表3-6语言选项5表3-7库选项5表3-8许可证选项6表3-9废弃的选项7表3-10输出选项7表3-11运行时性能选项8表3-12预处理程序选项10表3-13文件配置选项10表3-14参考选项11表3-15源文件选项11表3-16模板选项11xxii《C++用户指南》2005年11月表3-17线程选项12表4-1链接程序作用域声明说明符2表10-1在不同架构上结构和联合的传递4表11-1iostream初始核心类6表11-2多线程安全的可重入公共函数7表12-1C++编译器附带的库2表12-2链接C++库的编译器选项9表12-3头文件搜索示例14表13-1C++标准库头文件2表13-2C++标准库手册页3表14-1iostream例程头文件3表14-2iostream预定义的控制器15表14-3iostream手册页概述21表14-4iostream术语22表15-1复数运算库函数4表15-2复数数学函数和三角函数4表15-3复数运算库函数的默认错误处理6表15-4类型complex的手册页8表A-1选项语法格式示例1表A-2选项子节2表A-3预定义的宏8表A-4-erroff值13表A-5-errwarn值14表A-6-fast扩展15表A-7兼容模式和标准模式的-features值18表A-8仅用于标准模式的-features值19表A-9仅用于兼容模式的-features值20表A-10-filt值22表A-11-fns值25表A-12-fprecision值26表xxiii表A-13-fround值27表A-14-fsimple值28表A-15-ftrap值30表A-16-instances值38表A-17用于兼容模式的-library值42表A-18用于标准模式的-library值42表A-19-Qoption值53表A-20-Qproduce值54表A-21-staticlib值56表A-22-template值60表A-23-verbose值63表A-24SPARC平台的-xarch值69表A-25x86平台的-xarch值72表A-26-xcache的值77表A-27-xchar值79表A-28-xcheck值80表A-29-xchip值81表A-30-xcode值82表A-31-xcrossfile值84表A-32-xdebugformat标志85表A-33-xdumpmacros值86表A-34-xF值91表A-35-xinline值93表A-36-xipo值95表A-37-xldscope值99表A-38-xlinkopt值102表A-39-xmemalign的对齐和行为值105表A-40-xmemalign示例105表A-41-xmodel标志106表A-42-xnativeconnect值107xxiv《C++用户指南》2005年11月表A-43-xopenmp值113表A-44-xport64值121表A-45-xprefetch值125表A-46-xprefecth_level值128表A-47-xregs值132表A-48-xrestrict值133表A-49SPARC平台的-xtarget值136表A-50-xtarget的SPARC平台扩展137表A-51x86架构上的-xtarget扩展141表A-52-xthreadvar的值143表A-53-xtrigraphs值144表A-54-xvector标志147表A-55-Y标志148表B-1平台上最严格的对齐10表B-2存储大小和默认对齐字节数11xxv代码样例代码样例6-1本地类型用作模板参数问题的示例11代码样例6-2友元声明问题的示例12代码样例11-1检查错误状态8代码样例11-2调用gcount9代码样例11-3用户定义的I/O操作9代码样例11-4禁用多线程安全10代码样例11-5切换到多线程不安全10代码样例11-6在多线程不安全的对象中使用同步11代码样例11-7新增类11代码样例11-8新增类的分层结构12代码样例11-9新增函数12代码样例11-10使用锁定操作的示例15代码样例11-11令I/O操作和错误检查独立化16代码样例11-12销毁共享对象17代码样例11-13以多线程安全方式使用iostream对象18代码样例14-1string提取运算符7代码样例A-1预处理程序示例程序foo.
cc11代码样例A-2使用-E选项的foo.
cc的预处理程序输出11代码样例A-3带两个指针的循环134xxvi《C++用户指南》2005年11月xxvii阅读本书之前本手册指导您使用SunStudio11的C++编译器,并提供了有关命令行编译器选项的详细信息.
本手册适用于具有C++使用经验并对Solaris操作系统和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.
xxviii《C++用户指南》2005年11月印刷约定表P-1字体约定字体**浏览器的设置可能会与这些设置不同.
含义示例AaBbCc123命令、文件和目录的名称;计算机屏幕输出.
编辑.
login文件.
使用ls-a列出所有文件.
%Youhavemail.
AaBbCc123用户键入的内容,与计算机屏幕输出的显示不同.
%suPassword:AaBbCc123保留未译的新词或术语以及要强调的词.
要使用实名或值替换的命令行变量.
这些称为class选项.
要删除文件,请键入rmfilename.
新词术语强调新词或术语以及要强调的词.
您必须成为超级用户才能执行此操作.
《书名》书名阅读《用户指南》的第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阅读本书之前xxixShell提示符支持的平台此SunStudio发行版本支持使用SPARC和x86系列处理器体系结构(UltraSPARC、SPARC64、AMD64、Pentium和XeonEM64T)的系统.
通过访问http://www.
sun.
com/bigadmin/hcl中的硬件兼容性列表,可以了解您在使用的Solaris操作系统版本的支持系统.
这些文档列出了实现各个平台类型的所有差别.
在本文档中,这些与x86有关的术语具有以下含义:"x86"是指较大的64位和32位x86兼容产品系列.
"x64"表示有关AMD64或EM64T系统的特定64位信息.
"32位x86"表示有关基于x86的系统的特定32位信息.
有关所支持的系统,请参见硬件兼容性列表.
访问SunStudio软件和手册页SunStudio软件及其手册页未安装到/usr/bin/和/usr/share/man标准目录中.
要访问软件,必须正确设置PATH环境变量(请参见第xxx页的"访问软件").
要访问手册页,必须正确设置MANPATH环境变量(请参见第xxx页的"访问手册页").
Shell提示符Cshellmachine-name%Cshell超级用户machine-name#Bourneshell、Kornshell和GNUBourne-Againshell$Bourneshell、Kornshell和GNUBourne-Againshell的超级用户#xxx《C++用户指南》2005年11月有关PATH变量的详细信息,请参见csh(1)、sh(1)、ksh(1)和bash(1)手册页.
有关MANPATH变量的详细信息,请参见man(1)手册页.
有关设置PATH变量和MANPATH变量以访问此发行版本的详细信息,请参见安装指南或询问系统管理员.
注–本节中的信息假设SunStudio软件安装在Solaris平台上的/opt目录中和Linux平台上的/opt/sun目录中.
如果未将软件安装在默认目录中,请询问系统管理员以获取系统中的相应路径.
访问软件使用以下步骤来决定是否需要更改PATH变量以访问该软件.
决定是否需要设置PATH环境变量1.
通过在命令提示符后键入以下内容以显示PATH变量的当前值.
2.
在Solaris平台上,查看输出中是否包含有/opt/SUNWspro/bin的路径字符串.
在Linux平台上,查看输出中是否包含有/opt/sun/sunstudio11/bin的路径字符串.
如果找到该路径,则说明已设置了访问该软件的PATH变量.
如果没有找到该路径,则按照下一步的说明来设置PATH环境变量.
设置PATH环境变量以实现对软件的访问在Solaris平台上,将以下路径添加到PATH环境变量中.
如果以前安装了ForteDeveloper软件、SunONEStudio软件,或其他发行版本的SunStudio软件,则将以下路径添加到这些安装路径之前.
/opt/SUNWspro/bin在Linux平台上,将以下路径添加到PATH环境变量中.
/opt/sun/sunstudio11/bin访问手册页使用以下步骤决定是否需要更改MANPATH变量以访问手册页.
%echo$PATH阅读本书之前xxxi决定是否需要设置MANPATH环境变量1.
通过在命令提示符后键入以下内容以请求dbx手册页.
2.
请查看输出(如果有).
如果找不到dbx(1)手册页或者显示的手册页不是软件当前版本的手册页,请按照下一步的说明来设置MANPATH环境变量.
设置MANPATH环境变量以实现对手册页的访问在Solaris平台上,将以下路径添加到MANPATH环境变量中.
/opt/SUNWspro/man在Linux平台上,将以下路径添加到MANPATH环境变量中.
/opt/sun/sunstudio11/man访问集成开发环境SunStudio集成开发环境(integrateddevelopmentenvironment,IDE)提供了创建、编辑、生成、调试C、C++或Fortran应用程序并分析其性能的模块.
启动IDE的命令是sunstudio.
有关该命令的详细信息,请参见sunstudio(1)手册页.
IDE是否可以正确操作取决于IDE能否找到核心平台.
sunstudio命令查找两个位置的核心平台:该命令首先查找Solaris平台上的默认安装目录/opt/netbeans/3.
5V11和Linux平台上的默认安装目录/opt/sun/netbeans/3.
5V11.
如果该命令在默认目录找不到核心平台,则它会假设包含IDE的目录和包含核心平台的目录均安装在同一位置上.
例如,在Solaris平台上,如果包含IDE的目录的路径是/foo/SUNWspro,则该命令会在/foo/netbeans/3.
5V11中查找核心平台.
在Linux平台上,如果包含IDE的目录的路径是/foo/sunstudio11,则该命令会在/foo/netbeans/3.
5V11中查找核心平台.
如果核心平台未安装在sunstudio命令查找它的任一位置上,则客户端系统上的每个用户必须将环境变量SPRO_NETBEANS_HOME设置为安装核心平台的位置(/installation_directory/netbeans/3.
5V11).
%mandbxxxxii《C++用户指南》2005年11月在Solaris平台上,IDE的每个用户还必须将/installation_directory/SUNWspro/bin添加到其他任何ForteDeveloper软件、SunONEStudio软件或SunStudio软件发行版本路径前面的$PATH中.
在Linux平台上,IDE的每个用户还必须将/installation_directory/sunstudio11/bin添加到其他任何发行版本的SunStudio软件路径前面的$PATH中.
路径/installation_directory/netbeans/3.
5V11/bin不能添加到用户的$PATH中.
访问SunStudio文档您可以访问下列位置的文档:可以通过随软件一起安装在本地系统或网络上的文档索引获取文档,位置为Solaris平台上的file:/opt/SUNWspro/docs/zh/index.
html和Linux平台上的file:/opt/sun/sunstudio11/docs/zh/index.
html.
如果未将软件安装在Solaris平台上的/opt目录中或Linux平台上的/opt/sun目录中,请询问系统管理员以获取系统中的相应路径.
大多数的手册都可以从docs.
sun.
comsmWeb站点获取.
以下书目只能从Solaris平台上安装的软件中找到:《标准C++库类参考》《标准C++库用户指南》《Tools.
h++类库参考》《Tools.
h++用户指南》适用于Solaris平台和Linux平台的发行说明可以通过docs.
sun.
comWeb站点获取.
在IDE中通过"帮助"菜单以及许多窗口和对话框上的"帮助"按钮,可以访问IDE所有组件的联机帮助.
您可以通过Internet访问docs.
sun.
comWeb站点(http://docs.
sun.
com)以阅读、打印和购买SunMicrosystems的各种手册.
如果找不到手册,请参见和软件一起安装在本地系统或网络中的文档索引.
注–Sun对本文档中提到的第三方Web站点的可用性不承担任何责任.
对于此类站点或资源中的(或通过它们获得的)任何内容、广告、产品或其他资料,Sun并不表示认可,也不承担任何责任.
对于因使用或依靠此类站点或资源中的(或通过它们获得的)任何内容、产品或服务而造成的或连带产生的实际或名义损坏或损失,Sun概不负责,也不承担任何责任.
阅读本书之前xxxiii使用易读格式的文档该文档以易读格式提供,以方便残障用户使用辅助技术进行阅读.
您还可以按照下表所述,找到文档的易读版本.
如果未将软件安装在/opt目录中,请询问系统管理员以获取系统中的相应路径.
相关文档对于Solaris平台,下表描述的相关文档可以在/opt/SUNWspro/docs/zh/index.
html和http://docs.
sun.
com上获取.
如果未将软件安装在/opt目录中,请询问系统管理员以获取系统中的相应路径.
对于Linux平台,下表描述的相关文档可以在file:/opt/sun/sunstudio11/docs/zh/index.
html和http://docs.
sun.
com上获取.
如果未将软件安装在/opt/sun目录中,请询问系统管理员以获取系统中的相应路径.
文档类型易读版本的格式和位置手册(第三方手册除外)HTML,位于http://docs.
sun.
com第三方手册:《标准C++库类参考》《标准C++库用户指南》《Tools.
h++类库参考》《Tools.
h++用户指南》HTML,位于Solaris平台上所安装软件中的文档索引file:/opt/SUNWspro/docs/zh/index.
html自述文件HTML,位于SunDeveloperNetwork门户网站http://developers.
sun.
com/prodtech/cc/documentation/手册页HTML,位于安装的软件上的文档索引,位置为Solaris平台上的file:/opt/SUNWspro/docs/zh/index.
html和Linux平台上的file:/opt/sun/sunstudio11/docs/zh/index.
html.
联机帮助HTML,可通过IDE中的"帮助"菜单和"帮助"按钮访问发行说明HTML,位于http://docs.
sun.
com文档标题描述文档标题描述xxxiv《C++用户指南》2005年11月访问相关的Solaris文档下表描述了可从docs.
sun.
comWeb站点上获取的相关文档.
访问相关的C++手册页本手册提供了可用于C++库的手册页列表.
下表列出了与C++相关的其他手册页.
文档集合文档标题描述Solaris参考手册集合请参见手册页部分的标题.
提供有关Solaris操作系统的信息.
Solaris软件开发者集合《链接程序和库指南》介绍了Solaris链接编辑器和运行时链接程序的操作.
标题描述c++filt按顺序复制每个文件名,并在解码类似C++还原名称的符号之后将文件名写入标准输出dem还原指定的一个或多个C++名称fbe从汇编语言源文件创建对象文件fpversion输出系统CPU和FPU的相关信息gprof生成程序的可执行性能分析数据inline扩展汇编程序的内联过程调用lex生成词法分析程序rpcgen生成C/C++代码以实现RPC协议sigfpe允许对指定SIGFPE代码进行信号处理stdarg处理变量参数列表varargs处理变量参数列表版本显示对象文件或二进制文件的版本标识yacc将上下文无关的语法转换成一组表,用于执行LALR(1)分析算法的简单自动化阅读本书之前xxxv其他公司出版的书籍以下是部分C++语言书籍的列表:TheC++ProgrammingLanguage3rdedition,BjarneStroustrup所著(Addison-Wesley,1997).
TheC++StandardLibrary,NicolaiJosuttis所著(Addison-Wesley,1999).
GenericProgrammingandtheSTL,MatthewAustern所著(Addison-Wesley,1999).
StandardC++IOStreamsandLocales,AngelikaLanger和KlausKreft所著(Addison-Wesley,2000).
ThinkinginC++,Volume1,SecondEdition,BruceEckel所著(PrenticeHall,2000).
TheAnnotatedC++ReferenceManual,MargaretA.
Ellis和BjarneStroustrup所著(Addison-Wesley,1990).
DesignPatterns:ElementsofReusableObject-OrientedSoftware,ErichGamma、RichardHelm、RalphJohnson和JohnVlissides所著(Addison-Wesley,1995).
C++Primer,ThirdEdition,StanleyB.
Lippman和JoseeLajoie所著(Addison-Wesley,1998).
EffectiveC++-50WaystoImproveYourProgramsandDesignsSecondEdition,ScottMeyers所著(Addison-Wesley,1998).
MoreEffectiveC++-35WaystoImproveYourProgramsandDesigns,ScottMeyers所著(Addison-Wesley,1996).
开发者资源访问SunDeveloperNetworkSunStudio门户网站http://developers.
sun.
com/prodtech/cc以查找以下经常更新的资源:关于编程技术和最佳实例的文章有关编程小技巧的知识库软件的文档,以及随软件一同安装的文档的更正信息有关支持级别的信息用户论坛可下载的代码样例xxxvi《C++用户指南》2005年11月新技术预览SunStudio门户网站是SunDeveloperNetwork网站http://developers.
sun.
com上的很多额外开发者资源之一.
联系Sun技术支持如果您遇到通过本文档无法解决的技术问题,请访问以下网址:http://www.
sun.
com/service/contactingSun欢迎您提出意见Sun致力于提高其文档的质量,并十分乐意收到您的意见和建议.
您可以通过以下网址提交您的意见和建议:http://www.
sun.
com/hwdocs/feedback请在电子邮件的主题行中注明文档的文件号码.
例如,本文档的文件号码是819-4815-10.
第部分IC++编译器1-1第1章C++编译器本章提供有关以下内容的信息:第1-1页"SunStudio10C++5.
8编译器的新特性和新功能".
第1-3页"SunStudio10C++5.
7编译器的新特性和新功能".
第1-5页"C++自述文件".
第1-6页"手册页".
第1-6页"C++实用程序".
第1-6页"本地语言支持".
1.
1SunStudio10C++5.
8编译器的新特性和新功能本节简要介绍在SunStudio10C++5.
8编译器发行版本中引入的C编译器的新特性和新功能.
有关详细的说明,请参见每项的交叉引用.
用于x86开发的-xarch新标志-xarch选项目前支持将以下新标志用于x86平台开发:amd64a、pentium_proa、ssea、sse2a.
请参见第A-69页的第A.
2.
105节"-xarch=isa".
支持x86-xpagesize选项目前为x86平台和SPARC启用了-xpagesize、-xpagesize_heap、-xpagesize_stack选项.
请参见第A-114页的第A.
2.
147节"-xpagesize=n".
用于指定x86内存模型的-xmodel新选项通过使用-xmodel新选项,可以在64位AMD体系结构上指定内核、小型或中型内存模型.
如果全局变量和静态变量的大小超过了2千兆字节,请指定-xmodel=medium.
否则,请使用-xmodel=small默认设置.
有关详细信息,请参见第A-106页的第A.
2.
140节"-xmodel=[a]".
1-2《C++用户指南》2005年11月支持SSE/SSE2整型介质内部函数本发行版本支持SSE2128位XMM寄存器整型介质指令的内部函数.
在源代码中包含sunmedia_intrin.
h头文件,并指定-xbuiltin选项以利用这些函数.
再者,这些内部函数需要SSE2支持,因此,请指定-xarch=sse2、-xarch=amd64或-xtarget=opteron等选项.
实质上,编译器为这些内部函数生成内联代码.
这比通过汇编语言处理这些指令简单一些,并且编译器可以对其进行优化.
有关内部函数的详细信息、头文件中包含的函数原型以及这些函数使用的数据类型的说明,请参见《用于Linux系统的Intel(R)C++编译器》手册中的"IntelC++内部函数参考"一节.
用于x86SSE2平台的-xvector新标志利用-xvector选项,可以自动生成向量库函数调用和/或生成SIMD(SingleInstructionMultipleData,单指令多数据)指令.
有关详细信息,请参见第A-147页的第A.
2.
173节"-xvector[=a]".
用于SPARC的二进制文件优化器通过-xbinopt新选项,编译器可以准备由binopt(1)二进制文件优化器进一步优化的二进制文件.
有关详细信息,请参见第A-75页的第A.
2.
107节"-xbinopt={prepare|off}".
从函数模板调用相关静态函数C++标准规定,取决于模板参数的函数调用只能引用具有外部链接的可见函数声明.
如果应用程序代码取决于忽略此规则并从函数模板中调用相关静态函数的编译器,则指定-features=[no%]tmplrefstatic.
有关详细信息和示例,请参见第A-17页的第A.
2.
19节"-features=a[,a.
.
.
]".
SPARC-xtarget和-xchip的新值-xtarget的新标志ultra3iplus、ultra4plus和ultraT1以及-xchip的新标志ultra3iplus、ultra4plus和ultraT1为UltraSPARCIIIiplus、UltraSPARCT1和UltraSPARCIVplus处理器提供代码生成.
有关详细信息,请参见第A-136页的第A.
2.
167节"-xtarget=t"和第A-80页的第A.
2.
113节"-xchip=c".
新的调试器信息格式C++编译器目前可以使用dwarf格式来生成调试器信息.
默认格式仍然为stabs格式,但可以通过将新选项-xdebugformat设置为-xdebugformat=dwarf来生成dwarf数据.
请参见第A-85页的第A.
2.
116节"-xdebugformat=[stabs|dwarf]".
STACKSIZE环境变量增强功能已增强STACKSIZE环境变量的语法,可接受用于表示从属线程栈大小的单位关键字:B表示字节;K表示千字节;M表示兆字节;G表示千兆字节.
例如,setenvSTACKSIZE8192将从属线程栈大小设置为8MB.
1235B将从属线程栈大小设置为1235字节;1235G将其设置为1235千兆字节.
默认情况下,没有后缀字母的整数值仍然为千字节.
OpenMP自动确定作用域第1章C++编译器1-3自动确定作用域目前适用于C++程序.
SunStudio《OpenMPAPI用户指南》的第3章中介绍了该功能.
1.
2SunStudio10C++5.
7编译器的新特性和新功能本节简要介绍在SunStudio10C++5.
7编译器发行版本中引入的C++编译器的新特性和新功能.
有关详细的说明,请参见每项的交叉引用.
-xarch新选项-xarch=amd64指定了64位AMD指令集编译.
有关-xarch=amd64的详细信息,请参见第A-69页的第A.
2.
105节"-xarch=isa".
-xtarget新选项-xtarget=opteron为32位AMD编译指定了-xarch、-xchip和-xcache设置.
有关-xtarget=opteron的详细信息,请参见第A-136页的第A.
2.
167节"-xtarget=t".
注–要生成64位代码,您必须在命令行中-fast和-xtarget的右侧指定-xarch=amd64.
例如,指定CC-fast-xarch=amd64或CC-xtarget=opteron-xarch=amd64.
-xtarget=opteron新选项并不自动生成64位代码.
它扩展为-xarch=sse2、-xchip=opteron和-xcache=64/64/2:1024/64/16,而产生32位代码.
-fast选项也会产生32位代码,因为它也是一个定义-xtarget=native的宏.
除传统SPARC平台外,现有-xarch=generic64选项现在还支持x86平台.
如果指定了-xarch=amd64,C++编译器现在预定义__amd64和__x86_64.
利用-xregs选项-xregs=[no%]frameptr仅限x86的新标志,您可以将帧指针寄存器用作未分配的被调用方保存寄存器以提高应用程序的运行时性能.
有关-xregs=[no%]frameptr的详细信息,请参见第A-131页的第A.
2.
160节"-xregs=r[,r.
.
.
]".
C++编译器现在支持模板-模板参数.
这意味着,可以使用本身就是模板的参数来指定模板定义,而不是使用类型或值来指定.
请回想一下,在类型上实例化的模板本身就是类型.
考虑以下代码示例:templateclassMyClass{.
.
.
};std::list>x;1-4《C++用户指南》2005年11月因为MyClass是一种类型,所以代码示例并不使用模板-模板参数.
然而,在以下代码示例中,类模板C的参数是类模板,而对象x则是C的实例,它使用类模板A作为其参数.
C的成员y具有类型A.
在默认标准模式下,C++编译器现在允许嵌套类访问封装类的专有成员.
C++标准规定嵌套类没有封装类成员的特殊访问权限.
然而,大多数人认为这种限制不合理,因为成员函数拥有专有成员的访问权限,因此,成员类也应该有此权限.
在以下示例中,函数foo试图访问类outer的专有成员.
按照C++标准,函数没有访问权限,除非将其声明为友元函数:C++委员会正在采纳对访问规则所做的更改,以便给成员类授予与成员函数相同的访问权限.
由于预料到将会更改语言规则,很多编译器已经实现了这种规则.
要恢复旧的编译器行为,而禁用这种访问权限,请使用编译器选项-features=no%nestedaccess.
默认为-features=nestedaccess.
有关-features的详细信息,请参见第A-17页的第A.
2.
19节"-features=a[,a.
.
.
]".
此发行版在基于x86系统的Solaris操作系统和基于SPARC系统的Solaris操作系统上提供了OpenMPAPI以实现共享内存并行性.
这两种平台现在都启用相同的功能.
//普通类模板templateclassA{Tx;};//具有模板参数的类模板templateclassV>classC{Vy;};//在模板上实例化CCx;classouter{inti;//在outer中是专有的classinner{intfoo(outer*p){returnp->i;//无效}};};第1章C++编译器1-51.
3标准一致性C++编译器(CC)支持C++ISO国际标准ISOIS14882:1998,编程语言C++.
当前发行版本附带的自述文件描述了与标准需求的所有差异.
在SPARC平台上,编译器提供了对SPARCV8和SPARCV9(包括UltraSPARC实现)优化开发功能的支持.
在Prentice-HallforSPARCInternational发行的第8版(ISBN0-13-825001-4)和第9版(ISBN0-13-099227-5)SPARCArchitectureManual中定义了这些功能.
在本文档中,"标准"是指与上面列出的标准版本相一致.
"非标准"或"扩展"是指超出这些标准版本的功能.
负责标准的一方可能会不时地修订这些标准.
C++编译器兼容的适用标准版本可能被修订或替换,这将会导致以后的SunC++编译器发行版本在功能上与旧的发行版本产生不兼容.
1.
4C++自述文件C++编译器的自述文件强调了关于编译器的重要信息,其中包括:在手册印刷之后发现的信息新特性和更改的特性软件更正问题和解决办法限制和不兼容可发送库未实现的标准要查看C++自述文件的文本格式文件,请在命令提示符后键入以下命令:要访问自述文件的HTML格式文件,请在您的NetscapeCommunicator4.
0或兼容版本的浏览器中打开以下文件:/opt/SUNWspro/docs/zh/index.
html(如果您的C++编译器软件没有安装在/opt目录中,请通过系统管理员获取系统中的相应路径.
)浏览器可以显示HTML文档的索引.
要打开自述文件,请在索引中查找它的对应条目,然后单击主题.
example%CC-xhelp=readme1-6《C++用户指南》2005年11月1.
5手册页联机手册(man)页提供了关于命令、函数、例行程序以及收集这些信息的文档.
可以通过运行以下命令来显示手册页:在整个C++文档中,手册页参考以主题名称和手册节编号显示:cc(1)通过mancc进行访问.
其他部分(例如用ieee_flags(3M)表示的节)要使用man命令和该命令的-s选项来访问:1.
6C++实用程序以下C++实用程序现已并入传统的UNIX工具并且与UNIX操作系统捆绑在了一起:lex生成文本简单词法分析的程序yacc根据语法生成C函数分析输入流prof生成程序模块的执行性能分析gprof按过程来配置程序运行时性能tcov按语句来配置程序运行时性能关于这些UNIX工具的详细信息,请参见《程序性能分析工具》和相关的手册页.
1.
7本地语言支持此发行版本的C++支持使用英语以外的其他语言进行应用程序的开发,包括了大多数欧洲语言和日语.
因此,您可以十分便捷地将应用程序从一种语言切换到另一种语言.
此功能被称为国际化.
通常,C++编译器按如下方式实现国际化:C++从国际化的键盘识别ASCII字符(也就是说,它具有键盘独立性和8位清除).
C++允许使用本地语言打印某些消息.
example%mantopicexample%man-s3Mieee_flags第1章C++编译器1-7C++允许在注释、字符串和数据中使用本地语言.
C++只支持符合扩展UNIX字符(EUC)的字符集,在该字符集中字符串内的每个空字节是一个空字符,而每个"/"的ascii值是"/"字符.
变量名称不能国际化,必须使用英文字符集.
您可以设置语言环境将应用程序从一种本地语言更改为另一种语言.
关于这一点和其他本地语言支持功能的信息,请参见操作系统文档.
1-8《C++用户指南》2005年11月2-1第2章使用C++编译器本章描述了如何使用C++编译器.
任何编译器的主要用途是将高级语言(如C++)编写的程序转换成目标计算机硬件可执行的数据文件.
您可以使用C++编译器完成以下任务:将源文件转换成可重定位的二进制(.
o)文件、静态(归档)库(.
a)文件(使用-xar)或动态(共享)库(.
so)文件.
其中二进制文件可以在以后链接成可执行文件.
将对象文件或库文件(或两者)链接或重链接成可执行文件启用运行时调试(-g)来编译可执行文件启用运行时语句或过程级别的文件配置(-pg)来编译可执行文件2.
1入门本节简要概述了如何使用C++编译器编译和运行C++程序.
关于命令行选项的完整参考,请参见附录A.
注–本节中的命令行示例显示了CC的用法.
打印输出可能会稍有不同.
生成和运行C++程序的基本步骤包括:1.
使用编辑器创建具有表2-1中列出的有效后缀之一的C++源文件2.
调用编译器来生成可执行文件3.
通过输入可执行文件的名称来启动程序2-2《C++用户指南》2005年1月以下程序在屏幕上显示消息:在此示例中,CC编译源文件greetings.
cc,并且在默认情况下将编译可执行程序生成a.
out文件.
要启动程序,请在命令行提示符后键入可执行文件a.
out的名称.
按传统方法,UNIX编译器为可执行文件a.
out命名.
每次编译都写入到同一个文件是比较笨拙的方法.
另外,如果已经有这样一个文件存在,下次运行编译器时该文件将被覆盖.
如以下示例所示,改为使用-o编译器选项来指定可执行输出文件的名称:在此示例中,-o选项告知编译器将可执行代码写入文件greetings.
(由单独源文件组成的程序通常提供无后缀的源文件名称.
)或者,可以在每次编译后使用mv命令来重命名默认的a.
out文件.
无论是哪种方式,都可以键入可执行文件的名称来运行程序:2.
2调用编译器本节的其他部分讨论了使用CC命令的约定、编译器源代码行指令和编译器使用的其他有关问题.
example%catgreetings.
cc#includeintmain(){std::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-10《C++用户指南》2005年1月2.
5.
3预定义的名称附录中的表A-3显示了预定义的宏.
您可以在#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,1058708kavailable第2章使用C++编译器2-112.
6.
2增加交换空间使用mkfile(1M)和swap(1M)来增加工作站上交换空间的大小.
(您必须成为超级用户才能执行该操作.
)mkfile命令创建指定大小的文件,而swap-a将文件增加到系统交换空间:2.
6.
3虚拟内存的控制在-xO3或更高级别上编译大型例程(单个过程中包含了几千行代码)会需要大量的内存.
在这种情况下,系统性能可能降低.
您可以通过限制单个进程的可用虚拟内存量来控制这种情况.
要限制shshell的虚拟内存,请使用ulimit命令.
更多信息请参见sh(1)手册页.
以下示例显示了如何将虚拟内存限制为16M.
在cshshell中,使用limit命令来限制虚拟内存.
更多信息请参见csh(1)手册页.
下一个示例也显示了如何将虚拟内存限制为16M.
这些示例都使优化器在数据空间达到16M时尝试恢复.
虚拟空间的限制不能大于系统总的可用交换空间.
在实际使用时,虚拟空间的限制要足够的小,以允许在大型编译过程中正常使用系统.
请确保编译不会消耗一半以上的交换空间.
对于32M的交换空间,请使用以下命令:在shshell中:example#mkfile-v90m/home/swapfile/home/swapfile94317840bytesexample#/usr/sbin/swap-a/home/swapfileexample$ulimit-d16000example%limitdatasize16Mexample$ulimit-d160002-12《C++用户指南》2005年1月在cshshell中:最佳设置取决于要求的优化程度、实际内存量和可用的虚拟内存量.
2.
6.
4内存要求工作站至少需要64M的内存,推荐使用128M.
要决定实际内存,请使用以下命令:2.
7简化命令您可以通过使用CCFLAGS环境变量或通过使用make来定义特殊的shell别名,简化复杂的编译器命令.
2.
7.
1在CShell中使用别名以下示例为带有常用选项的命令定义了别名.
下面的示例使用了别名CCfx.
命令CCfx现在等价于:example%limitdatasize16Mexample%/usr/sbin/dmesg|grepmemmem=655360K(0x28000000)availmem=602476544example%aliasCCfx"CC-fast-xnolibmil"example%CCfxany.
Cexample%CC-fast-xnolibmilany.
C第2章使用C++编译器2-132.
7.
2使用CCFLAGS来指定编译选项您可以设置CCFLAGS变量来指定选项.
CCFLAGS变量可以在命令行中显式使用.
下列示例说明了如何设置CCFLAGS(CShell):下面的示例显式使用CCFLAGS.
当您使用make时,如果CCFLAGS变量像上述示例那样设置,并且makefile的编译规则是隐式的,那么调用make会导致编译等价于:CC-xO2-xsbfiles.
.
.
2.
7.
3使用makemake实用程序是功能十分强大的程序开发工具,可以方便地和所有Sun编译器一起使用.
更多信息请参见make(1S)手册页.
2.
7.
3.
1和make一起使用CCFLAGS使用makefile的隐式编译规则时(即没有C++编译行),make程序自动使用CCFLAGS.
2.
7.
3.
2为Makefile增加后缀您可以将不同的文件后缀增加到makefile以使它们收入C++中.
以下示例将.
cpp增加为C++文件的有效后缀.
将SUFFIXES宏增加到makefile:SUFFIXES:.
cpp.
cpp~(此行可以放置在makefile的任何位置.
)example%setenvCCFLAGS'-xO2-xsb'example%CC$CCFLAGSany.
cc2-14《C++用户指南》2005年1月将以下各行增加到makefile.
缩进的行必须以制表符开头.
2.
7.
3.
3和标准库头文件一起使用make标准库文件的名称不包括.
h后缀.
相反,它们命名为istream、fstream等等.
此外,模板源文件命名为istream.
cc、fstream.
cc等等.
.
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$%$);.
.
.
};staticconstchar__func__[]="function-name";#includevoidmyfunc(void){printf("%s\n",__func__);}4-8《C++用户指南》2005年1月每次调用函数时,函数将把以下内容打印到标准输出流.
myfunc5-1第5章程序组织C++程序的文件组织需要比典参阅型的C程序更加小心.
本章说明了如何建立头文件和模板定义.
5.
1头文件创建有效的头文件是很困难的.
头文件通常必须适应C和C++的不同版本.
要容纳模板,请确保头文件可以采取多个包含(幂等).
5.
1.
1可适应语言的头文件可能需要开发能够包含在C和C++程序中的头文件.
不过,称为"传统C"的Kernighan和RitchieC(K&RC)、ANSIC、AnnotatedReferenceManualC++(ARMC++)以及ISOC++有时需要在单个头文件中对同一个程序元素给出不同的声明和定义.
(关于各个语言和版本的附加信息,请参见《C++迁移指南》.
)要使头文件能够被所有这些标准接受,可能需要使用基于预处理程序宏__STDC__和__cplusplus或其值的条件编译.
宏__STDC__在K&RC中没有定义,但在ANSIC和C++中都有定义.
使用这个宏可以从ANSIC或C++代码中区分出K&RC代码.
该宏最适用于从非原型函数定义中区分原型函数定义.
宏__cplusplus不在C中定义,但在C++中定义.
#ifdef__STDC__intfunction(char*C++&ANSIC声明#elseintfunction();//K&RC#endif5-2《C++用户指南》2005年1月注–C++的早期版本定义的是宏c_plusplus,而非__cplusplus.
宏c_plusplus现在不再定义.
使用__cplusplus宏的定义来区分C和C++.
这个宏在保护函数声明的extern"C"接口规范时非常有用,如以下示例所示.
为了防止不一致的extern"C"规范,请勿在extern"C"链接规范的作用域中放置#include指令.
在ARMC++中,__cplusplus宏值为1.
在ISOC++中,宏的值为199711L(标准年月用long常量来表示).
使用这个宏的值区分ARMC++和ISOC++.
这个宏值在保护模板语法的更改时极为有用.
5.
1.
2幂等头文件头文件应当是幂等的.
也就是说,多次包括头文件的效果和仅包括一次的效果完全相同.
该特性对于模板尤其重要.
通过设置预处理程序条件以防止头文件体多次出现,可以很好的实现幂等.
#include"header.
h"其他包括文件.
.
.
#ifdefined(__cplusplus)extern"C"{#endifintg1();intg2();intg3()#ifdefined(__cplusplus)}#endif//模板函数规范#if__cplusplusintpower(int,int);//ISOC++#endif#ifndefHEADER_H#defineHEADER_H/*头文件内容*/#endif第5章程序组织5-35.
2模板定义可以用两种方法组织模板定义:使用包括的定义和使用独立的定义.
包括的定义组织允许对模板编译进行更多的控制.
5.
2.
1包括的模板定义将模板的声明和定义放置在使用模板的文件中时,这就是包括定义的结构.
例如:使用模板的文件包括了包含模板声明和定义的文件时,使用模板的该文件也具有包括的定义组织.
例如:注–使模板头文件幂等是非常重要的.
(请参见第5-2页的第5.
1.
2节"幂等头文件".
)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);}5-4《C++用户指南》2005年1月5.
2.
2独立的模板定义组织模板定义的另一种方法是将定义保留在模板定义文件中,如以下示例所示.
模板定义文件不得包括任何非幂等的头文件,而且通常根本不包括任何头文件.
(请参见第5-2页的第5.
1.
2节"幂等头文件".
)注意,并非所有编译器都支持模板的独立定义模型.
一个单独的定义文件作为头文件时,该文件可能会被隐式包括在许多文件中.
因此,它不应该包含任何函数或变量定义(除非这些定义是模板定义的一部分).
一个单独的定义文件可以包含类型定义,包括typedef.
注–尽管模板定义文件的源文件通常会使用扩展名(即,.
c、.
C、.
cc、.
cpp、.
cxx或.
c++),但模板定义文件就是头文件.
如果需要,编译器会自动包括这些它们.
模板定义文件不可以单独编译.
如果将模板声明放置在一个文件中,而将模板定义放置在另一个文件中,则必须仔细考虑如何构造定义文件,如何命名定义文件和如何放置定义文件.
此外也需要向编译器显式指定定义的位置.
关于模板定义搜索规则的信息,请参见第7-7页的第7.
5节"模板定义搜索".
twice.
h#ifndefTWICE_H#defineTWICE_HtemplateNumbertwice(Numberoriginal);#endifTWICE_Htwice.
cctemplateNumbertwice(Numberoriginal){returnoriginal+original;}main.
cc#include"twice.
h"intmain(){returntwice(-3);}6-1第6章创建和使用模板有了模板,就可以采用类型安全方法参阅来编写适用于多种类型的单一代码.
本章介绍了模板的概念和函数模板上下文中的术语,讨论了更复杂的(更强大的)类模板,描述了模板的组成,此外还讨论了模板实例化、默认模板参数和模板专门化.
本章的结尾部分讨论了模板的潜在问题.
6.
1函数模板函数模板描述了仅用参数或返回值的类型来区分的一组相关函数.
6.
1.
1函数模板声明使用模板之前,请先声明.
以下示例中所示的声明提供了使用模板的足够信息,但没有提供实现模板的足够信息.
在本示例中,Number是模板参数,指定了模板描述的函数范围.
尤其特别的是Number是模板类型参数,该参数在模板定义中的使用代表了在使用模板的位置所决定的类型.
templateNumbertwice(Numberoriginal);6-2《C++用户指南》2005年1月6.
1.
2函数模板定义如果要声明模板,请先定义该模板.
定义提供了实现模板的足够信息.
以下示例定义了在前一个示例中声明的模板.
因为模板定义通常出现在头文件中,所以模板定义必须在多个编译单元中重复.
不过所有的定义都必须是相同的.
这种约束称为单次定义规则.
编译器不支持函数参数列表中非类型模板参数的表达式,如以下示例所示.
6.
1.
3函数模板用法声明后,模板可以像其他函数一样使用.
模板的使用由命名模板和提供函数参数组成.
编译器可以从函数参数类型推断出模板类型参数.
例如,您可以使用上面声明的模板,具体步骤如下所示.
如果模板参数不能从函数参数类型推断出,则调用函数时必须提供模板参数.
例如:6.
2类模板类模板描述了一组相关的类或数据类型,它们只能通过类型来区分:整数值、指向(或引用)具有全局链接的变量的指针、其他的组合.
类模板尤其适用于描述通用但类型安全的数据结构.
templateNumbertwice(Numberoriginal){returnoriginal+original;}//具有非类型模板参数的表达式//在函数参数列表中是不支持的templatevoidfoo(mytypetemplatevoidfoo(inta[I+J]doubletwicedouble(doubleitem){returntwice(item);}templateTfunc();//无函数参数intk=func();//显式提供模板参数第6章创建和使用模板6-36.
2.
1类模板声明类模板声明仅提供了类的名称和类的模板参数.
这种声明是不完整的类模板.
以下示例是命名为Array类的模板声明,该类可以将任何类型作为参数.
该模板是命名为String类的模板,该类将unsignedint作为参数.
6.
2.
2类模板定义类模板定义必须声明类数据和函数成员,如以下示例所示.
与函数模板不同,类模板可以同时具有类型参数(例如classElem)和表达式参数(例如unsignedSize).
表达式参数可以是:具有整数类型或枚举的值指向对象的指针或到对象的引用指向函数的指针或到函数的引用指向类成员函数的指针templateclassArray;templateclassString;templateclassArray{Elem*data;intsize;public:Array(intsz);intGetSize();Elem&operator[](intidx);};templateclassString{chardata[Size];staticintoverflows;public:String(char*initial);intlength();};6-4《C++用户指南》2005年1月6.
2.
3类模板成员定义类模板的完整定义需要类模板函数成员和静态数据成员的定义.
动态(非静态)数据成员由类模板声明完全定义.
6.
2.
3.
1函数成员定义模板函数成员的定义由模板参数专门化后跟函数定义组成.
函数标识符通过类模板的类名称和模板参数来限定.
以下示例说明了Array类模板的两个函数成员的定义,该模板具有template的模板参数专门化.
每个函数标识符都通过模板类名称和模板参数Array来限定.
该示例说明了String类模板的函数成员定义.
6.
2.
3.
2静态数据成员定义模板静态数据成员的定义由后跟变量定义的模板参数专门化组成,在此处变量标识符通过类模板名称和类模板实际参数来限定.
templateArray::Array(intsz){size=sz;data=newElem[size];}templateintArray::GetSize(){returnsize;}#includetemplateintString::length(){intlen=0;while(lenString::String(char*initial){strncpy(data,initial,Size);if(length()==Size)overflows++;}templateintString::overflows=0;第6章创建和使用模板6-56.
2.
4类模板的用法模板类可以在使用类型的任何地方使用.
指定模板类包括了提供模板名称和参数的值.
以下示例中的声明创建了基于Array模板的int_array变量.
变量的类声明和方法集与Array模板中的类声明和方法集相同,不同之处是Elem替换为int(请参见第6-5页的第6.
3节"模板实例化").
本示例中的声明使用String模板创建short_string变量.
需要任何其他成员函数时,您可以使用模板类成员函数.
6.
3模板实例化模板实例化包含了为模板参数的特定组合生成固定类或函数(实例).
例如,编译器生成了Array的类和Array的不同类.
通过替换模板类定义中模板参数的模板参数,可以定义这些新的类.
在上一节"类模板"所述的Array示例中,编译器在Elem出现的位置替换int.
6.
3.
1隐式模板实例化使用模板函数或模板类时需要实例.
如果这种实例还不存在,则编译器隐式实例化模板参数组合的模板.
Arrayint_array(100);Stringshort_string("hello");intx=int_array.
GetSize();intx=short_string.
length();6-6《C++用户指南》2005年1月6.
3.
2显式模板实例化编译器仅为实际使用的那些模板参数组合而隐式实例化模板.
该方法不适用于构造提供模板的库.
C++提供了显式实例化模板的功能,如以下示例所示.
6.
3.
2.
1模板函数的显式实例化要显式实例化一个模板函数,template关键字的后面应跟有该函数的声明(而不是定义);其中,函数识别符后面跟有模板参数.
在编译器可以推断出模板参数时,模板参数可以省略.
6.
3.
2.
2模板类的显式实例化要显式实例化模板类,请在template关键字后跟类的声明(无定义);而要实例化类标识符,请后跟模板参数.
显式实例化类时,所有的类成员也必须实例化.
6.
3.
2.
3模板类函数成员的显式实例化要显式实例化模板类函数成员,请在template关键字后跟函数的声明(无定义);而要实例化由模板类限定的函数标识符,请后跟模板参数.
templatefloattwice(floatoriginal);templateinttwice(intoriginal);templateclassArray;templateclassString;templateintArray::GetSize();templateintString::length();第6章创建和使用模板6-76.
3.
2.
4模板类静态数据成员的显式实例要显式实例化模板类静态数据成员,请在template关键字后跟成员的声明(无定义);而要实例化由模板类限定的成员标识符,请后跟模板参数.
6.
4模板组合可以用嵌套方式使用模板.
这种方式尤其适用于在通用数据结构上定义通用函数,与在标准C++库中相同.
例如,模板排序函数可以通过一个模板数组类进行声明:并定义为:上述示例定义了预先声明的Array类模板对象上的排序函数.
下一个示例说明了排序函数的实际用法.
templateintString::overflows;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;}}Arrayint_array(100);//构造整型数组sort(int_array);//排序该数组6-8《C++用户指南》2005年1月6.
5默认模板参数您可以将默认值赋予类模板(但不是函数模板)的模板参数.
如果模板参数具有默认值,则该参数后的所有参数也必须具有默认值.
模板参数仅能具有一个默认值.
6.
6模板专门化将模板参数的某些组合视为特殊的参数可以优化性能,如以下twice的示例所示.
或者,模板描述将无法处理一组可能的参数,如以下sort的示例所示.
模板专门化允许您定义实际模板参数给定组合的可选实现.
模板专门化覆盖了默认实例化.
6.
6.
1模板专门化声明使用模板参数的组合之前,您必须声明专门化.
以下示例声明了twice和sort的专用实现.
如果编译器可以明确决定模板参数,则您可以省略模板参数.
例如:templateclassArray;templateclassString;templateunsignedtwice(unsignedoriginal);templatesort(Arraystore);templateunsignedtwice(unsignedoriginal);templatesort(Arraystore);第6章创建和使用模板6-96.
6.
2模板专门化定义必须定义声明的所有模板专门化.
下例定义了上一节中声明的函数.
6.
6.
3模板专门化使用和实例化专门化与其他任何模板一样使用并实例化,除此以外,完全专用模板的定义也是实例化.
6.
6.
4部分专门化在前一个示例中,模板是完全专用的.
也就是说,模板定义了特定模板参数的实现.
模板也可以部分专用,这意味着只有某些模板参数被指定,或者一个或多个参数被限定到某种类型.
生成的部分专门化仍然是模板.
例如,以下代码样例说明了主模板和该模板的完全专门化.
以下代码说明了主模板部分专门化的示例.
示例1提供了第一个模板参数是int类型时的特殊模板定义.
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;}}templateclassA主模板templateclassA专门化templateclassA示例1templateclassAclassA示例36-10《C++用户指南》2005年1月示例2提供了第一个模板参数是任何指针类型时的特殊模板定义.
示例3为第一个模板参数是指针到指针的任何类型而第二个模板参数是char类型时的情况提供了特殊模板定义.
6.
7模板问题部分本节描述了使用模板时会遇到的问题.
6.
7.
1非本地名称解析和实例化有时模板定义使用模板参数或模板本身未定义的名称.
如此,编译器解决了封闭模板作用域的名称,该模板可以在定义或实例化点的上下文中.
名称可以在不同的位置具有不同的含义,产生不同的解析.
名称解析比较复杂.
因此,您不应该依赖除一般全局环境中提供的名称外的非本地名称.
也就是说,仅使用在任何地方都用相同方法声明和定义的非本地名称.
在以下示例中,模板函数converter使用了非本地名称intermediary和temporary.
这些名称在use1.
cc和use2.
cc中具有不同的定义,并且可能在不同编译器下产生不同的结果.
为了模板能可靠地工作,所有非本地名称(该示例中的intermediary和temporary)都必须在任何地方具有相同的定义.
非本地名称的一个常见的用法是模板内的cin和cout流.
有时编程人员要将流作为模板参数传递,这时就要引用到全局变量.
不过,cin和cout在任何地方都必须具有相同的定义.
use_common.
h//通用模板定义templateTargetconverter(Sourcesource){temporary=(intermediary)source;return(Target)temporary;}use1.
cctypedefintintermediary;inttemporary;#include"use_common.
h"use2.
cctypedefdoubleintermediary;unsignedinttemporary;#include"use_common.
h"第6章创建和使用模板6-116.
7.
2作为模板参数的本地类型模板实例化系统取决于类型名称,等价于决定哪些模板需要实例化或重新实例化.
因此本地类型用作模板参数时,会导致严重的问题.
小心在代码中也出现类似的问题.
例如:在file1.
cc中注册的Foo类型与在file2.
cc中注册的Foo类型不同.
以这种方法使用本地类型会出现错误和不可预料的结果.
代码样例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);6-12《C++用户指南》2005年1月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的参数,所以array的声明必须先于函数声明.
文件array.
h必须显示如下:friendostream&operator&);#ifndefARRAY_H#defineARRAY_H#include//下面两行将operatorclassarray;templatestd::ostream&operator&);templateclassarray{intsize;public:array();friendstd::ostream&operator(std::ostream&,constarray&);};#endif6-14《C++用户指南》2005年1月6.
7.
4在模板定义内使用限定名称C++标准需要具有限定名称的类型,该名称取决于用typename关键字显式标注为类型名称的模板参数.
即使编译器"知道"应该是类型,也需要具有限定名称的类型.
以下示例中的注释说明了需要用typename关键字来限定名称的类型.
6.
7.
5嵌套模板名称由于">>"字符序列解释为右移运算符,因此在一个模板名称中使用另一个模板名称时必须要非常小心.
确保将邻近的">"字符用至少一个空格分隔开.
例如,以下是形式错误的语句:被解释为:structsimple{typedefinta_type;staticinta_datum;};intsimple::a_datum=0;//不是类型templatestructparametric{typedefTa_type;staticTa_datum;};templateTparametric::a_datum=0;//不是类型templatestructexample{statictypenameT::a_typevariable1;//依存statictypenameparametric::a_typevariable2;//依存staticsimple::a_typevariable3;//不依存};templatetypenameT::a_type//依存example::variable1=0;//不是类型templatetypenameparametric::a_type//依存example::variable2=0;//不是类型templatesimple::a_type//不依存example::variable3=0;//不是类型Array>short_string_array(100)右移Array>short_string_array(100);第6章创建和使用模板6-15正确的语法为:6.
7.
6引用静态变量和静态函数在模板定义中,编译器不支持引用在全局作用域或名称空间中声明为静态的对象或函数.
如果生成了多个实例,则每个示例引用到了不同的对象,因此违背了单次定义规则(C++标准的3.
2节).
通常的失败指示是链接时丢失符号.
如果想要所有模板实例化共享单一对象,那么请使对象成为已命名空间的非静态成员.
如果想要模板类的每个实例化不同对象,那么请使对象成为模板类的静态成员.
如果想要模板函数每个实例化的不同对象,那么请使对象具有函数局部化属性.
6.
7.
7在同一目录中使用模板生成多个程序如果通过指定-instances=extern生成多个程序或库,那么建议在不同的目录中生成这些程序或库.
如果要在同一目录中生成多个程序,那么您需要清除不同生成程序之间的系统信息库.
这样可以避免出现任何不可预料的错误.
更多信息请参见第7-6页的第7.
4.
4节"共享模板系统信息库".
考虑具有make文件a.
cc、b.
cc、x.
h和x.
cc的以下示例.
注意该示例仅适用于指定-instances=extern时:Array>short_string_array(100);.
.
.
.
.
.
.
.
Makefile.
.
.
.
.
.
.
.
CCC=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*.
oab6-16《C++用户指南》2005年1月.
.
.
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();temp1.
create();}第6章创建和使用模板6-17如果同时生成了a和b,那么在两个生成之间增加makeclean.
以下命令会引起错误:以下命令不会产生任何错误:.
.
.
b.
cc.
.
.
#include"x.
h"intmain(){Xtemp1;temp1.
create();}example%makeaexample%makebexample%makeaexample%makecleanexample%makeb6-18《C++用户指南》2005年1月7-1第7章编译模板C++编译器在模板编译方面处理的工作要比传统UNIX编译器处理的工作多.
C++编译器必须按需为模板实例生成对象代码.
该编译器会使用模板系统信息库在多个独立的编译间共享模板实例,此外还接受某些模板编译选项.
编译器必须在各个源文件中定位模板定义,并维护模板实例和主线代码之间的一致性.
7.
1冗余编译给定标志-verbose=template后,C++编译器通知您模板编译期间的重要事件.
相反,给定默认-verbose=no%template时,编译器不会通知您.
+w选项可以指示模板实例化发生时其他潜在的问题.
7.
2系统信息库管理CCadmin(1)命令管理模板系统信息库.
例如,程序中的更改会引起某些实例化过量,这样会浪费存储空间.
CCadmin-clean命令(以前的ptclean)清除所有实例化和有关的数据.
实例化仅在需要时才重新创建.
7.
2.
1生成的实例为了生成模板实例,编译器将内联模板函数看作内联函数.
编译器像管理其他内联函数一样管理这些内联模板函数,另外本章中的说明不适用于模板内联函数.
7-2《C++用户指南》2005年11月7.
2.
2整个类实例化编译器通常实例化独立于其他成员的模板类成员,因此编译器仅实例化程序中使用的成员.
仅用于调试器的方法会因此而不正常地实例化.
有两种方法确保调试成员可用于调试器.
首先,编写使用模板类实例成员(否则无用)的非模板函数,不需要调用该函数.
其次,使用-template=wholeclass编译器选项,通知编译器实例化模板类的所有非模板非内联成员,前提是任何这些相同成员都是可实例化的.
ISOC++标准允许开发者编写模板类,因为并不是所有成员都可以使用模板参数.
只要非法成员未被实例化,程序就仍然完好.
ISOC++标准库使用了这种技术.
不过,-template=wholeclass选项实例化所有成员,因此在使用有问题的模板参数来进行实例化时就不能使用这种模板类.
7.
2.
3编译时实例化实例化是C++编译器从模板创建可用的函数或对象的过程.
C++编译器使用了编译时实例化,在编译对模板的引用时强制进行实例化.
编译时实例化的优点是:调试更为容易-错误消息出现在上下文中,同时允许编译器完整回溯到引用点.
模板实例化始终保持最新.
包括链接阶段在内的总编译时间减少了.
如果源文件位于不同的目录或您使用了具有模板符号的库,则模板可以多次实例化.
7.
2.
4模板实例的放置和链接从SunC++编译器的5.
5版本开始,实例将被放入特殊的地址区,并且链接程序可以识别并丢弃重复实例.
您可以指示编译器使用五个实例放置和链接方法之一:外部、静态、全局、显式和半显式.
外部实例适用于大多数程序的开发,并且满足以下条件时可以达到最好的执行效率:程序中的实例集比较小,但是每个编译单元引用了实例较大的子集.
很少有在多于一个或两个编译单元中引用的实例.
静态,过时-见下文.
默认的全局实例适用于所有程序的开发,并且当对象引用不同的实例时执行效率可以达到最好.
显式实例适用于某些需精确控制的应用程序编译环境.
第7章编译模板7-3半显式实例需要较少控制的编译环境,但是生成了较大的对象文件,并且有严格的使用规则.
本节讨论了五种实例放置和链接方法.
关于生成实例的详细信息,请参见第6-5页的第6.
3节"模板实例化".
7.
3外部实例对于外部实例方法,所有实例都放置在模板系统信息库中.
编译器确保只有一个一致的模板实例存在;这些实例既不是未定义的也不是多重定义的.
模板仅在需要时才重新实例化.
对于非调试代码,使用-instances=extern时的所有对象文件的总计大小小于使用-instances=global时的所有对象文件的总计大小.
模板实例接收系统信息库中的全局链接.
实例使用外部链接从当前编译单元引用.
注–如果以不同的步骤编译和链接并为编译步骤指定了-instance=extern,则也必须为链接步骤指定-instance=extern.
这种方法的缺点是更改程序或程序发生重大更改时必须清除缓存.
缓存是并行编译的瓶颈,因为使用dmake时每次只能有一个编译访问缓存.
另外,每个目录内仅能生成一个程序.
决定缓存中是否存在有效的模板实例比直接在主对象文件中创建实例(如果需要,用完后可以丢弃)要花费更长的时间.
使用instances=extern选项指定外部链接.
因为实例存储在模板系统信息库中,所以您必须使用CC命令将使用外部实例的C++对象链接到程序中.
如果要创建包含所有模板实例的库,则使用具有-xar选项的CC命令.
不要使用ar命令.
例如:有关详细信息,请参见第16章.
7.
3.
0.
1可能的缓存冲突指定-instance=extern时,请勿允许在同一目录中运行不同的编译器版本,以避免可能的缓存冲突.
使用-instances=extern模板模型时,请考虑以下问题:example%CC-xar-instances=extern-olibmain.
aa.
ob.
oc.
o7-4《C++用户指南》2005年11月请勿在同一目录中创建不相关的二进制文件.
在目录中创建任何二进制文件(.
o、.
a、.
so,可执行程序)都应该是相关的,在所有对象、函数的名称中,将公共区键入到两个或多个具有相同定义的对象文件.
在同一目录中同时运行多个编译是安全的,例如使用dmake时.
与另外一个链接步骤同时运行任何编译或链接步骤是不安全的.
"链接步骤"指创建库或可执行程序的任何操作.
确保makefile中的依存关系不允许任何内容与链接步骤以并行方式运行.
7.
3.
1静态实例注–-instances=static选项已过时.
没有任何理由再使用-instances=static,因为-instances=global现在向您提供了所有静态的优点而没有它的缺点.
以前编译器中提供的该选项用于克服C++5.
5中不存在的问题.
对于静态实例方法,所有实例都被放置在当前编译单元内.
因此,模板在每个重新编译期间重新实例化;这些实例不保存到模板系统信息库.
这种方法的缺点是不遵循语言语义,并且会生成很大的对象和可执行文件.
实例接收静态链接.
这些实例在当前编译单元外部是不可视的或不可用的.
因此,模板可以在多个对象文件中具有相同的实例化.
因为多重实例产生了不必要的大程序,所以对于不可能多重实例化模板的小程序可以使用静态链接.
静态实例的编译速度很快,因此这种方法也适用于修复并继续方式的调试.
(请参见《使用dbx调试程序》.
)注–如果您的程序取决于多个编译单元间的共享模板实例(例如模板类或模板函数的静态数据成员),请勿使用静态实例方法.
否则程序会工作不正常.
使用-instances=static编译器选项指定静态实例链接.
7.
3.
2全局实例与以前的编译器发行版本不同,本版本的编译器无需保护全局实例的多个副本.
这种方法的优点是通常由其他编译器接受的不正确源代码也能在这种模式中接受.
特别的是,从模板实例内对静态变量的引用是不合法的,但通常是可以接受的.
这种方法的缺点是单个对象文件会很大,原因是多个文件中模板实例有多个副本.
如果您使用-g选项(或没有该选项)编译调试的某些对象文件,那么很难预测是否可以获得链接到程序中模板实例的调试或非调试版本.
模板实例接收全局链接.
这些实例在当前编译单元外部是可视的和可用的.
第7章编译模板7-5使用-instances=global选项(默认选项)指定全局实例.
7.
3.
3显式实例在显式实例方法中,仅为显式实例化的模板生成实例.
隐式实例化不能满足该要求.
实例被放置在当前编译单元内.
因此,模板在每个重新编译期间重新实例化,这些模板不保存到模板系统信息库.
这种方法的优点是拥有最少的模板编译和最小的对象大小.
缺点是您必须手动执行所有的实例化.
模板实例接收全局链接.
这些实例在当前编译单元外部是可视的和可用的.
链接程序识别并丢弃重复项目.
使用-instances=explicit选项指定显式实例.
7.
3.
4半显式实例使用半显式实例方法时,仅为显式实例化或模板体内隐式实例化的模板生成实例.
那些被显式创建实例所需要的实例将会自动生成.
主线代码中隐式实例化不满足该要求.
实例被放置在当前编译单元内.
因此,模板在每个重新编译期间重新实例化;生成的实例接收全局链接,且不会被保存到模板系统信息库中.
使用-instances=semiexplicit选项指定半显式实例.
7.
4模板系统信息库模板系统信息库存储了多个独立编译之间的模板实例,因此模板实例仅当需要时才编译.
模板系统信息库包含了使用外部实例方法时模板实例化所需的所有非源文件.
系统信息库不用于其他种类的实例.
7.
4.
1系统信息库结构默认情况下,模板系统信息库包含在名为SunWS_cache的缓存目录中.
7-6《C++用户指南》2005年11月缓存目录包含在放置对象文件的目录中.
您可以通过设置SUNWS_CACHE_NAME环境变量更改缓存目录的名称.
注意,SUNWS_CACHE_NAME变量的值必须是目录名称,不能是路径的名称.
这是因为编译器自动将模板缓存目录放置到了对象文件目录中,因此编译器已经具有了路径.
7.
4.
2写入模板系统信息库编译器必须存储模板实例时,编译器将模板实例存储在对应于输出文件的模板系统信息库中.
例如,以下命令行将对象文件写入.
/sub/a.
o,并将模板实例写入.
/sub/SunWS_cache内包含的系统信息库中.
如果缓存目录不存在,且编译器需要实例化模板,则编译器将创建目录.
7.
4.
3从多模板系统信息库读取编译器从对应于编译器读取的对象文件的模板系统信息库读取.
也就是说,以下命令行从.
/sub1/SunWS_cache和.
/sub2/SunWS_cache读取,并且如果需要,则写入.
/SunWS_cache.
7.
4.
4共享模板系统信息库系统信息库内的模板不能违反ISOC++标准的单次定义规则.
也就是说,使用所有的模板时模板必须具有相同的源.
违反该规则会产生不可预料的行为.
确保不违反该规则的最简单和最保守的方法是在任何一个目录内仅生成一个程序或库.
两个不相关的程序可以使用相同类型的名称或外部名称来表示不同的内容.
如果程序共享模板系统信息库,则模板定义会出现冲突,会产生不可预料的结果.
7.
4.
5模板实例自动与-instances=extern一致模板系统信息库管理器确保了指定-instances=extern时,系统信息库中的实例状态与源文件保持一致并为最新.
例如,如果源文件用-g选项(即打开调试)编译,则从数据库所需的文件也用-g编译.
example%CC-osub/a.
oa.
ccexample%CCsub1/a.
osub2/b.
o第7章编译模板7-7此外,模板系统信息库会跟踪编译中的更改.
例如,如果设置-DDEBUG标志以定义名称DEBUG,则数据库进行跟踪.
如果在以后的编译中省略该标志,则编译器重新实例化设置依存关系的这些模板.
7.
5模板定义搜索使用独立定义模板组织时,模板定义在当前编译单元不可用,并且编译器必须搜索该定义.
本节描述了编译器如何找到定义.
定义搜索有点复杂且易于出错.
因此如果可能,您应该使用定义包括模板文件组织.
这样有助于避免一起定义搜索.
请参见第5-3页的第5.
2.
1节"包括的模板定义".
注–如果使用-template=no%extdef选项,则编译器不会搜索独立源文件.
7.
5.
1源文件位置约定无需某个选项文件提供特定的指示说明,编译器可以采用Cfront样式的方法来查找模板定义文件.
这种方法需要模板定义文件包含了与模板声明文件相同的基名.
该方法也需要模板定义文件位于当前include路径中.
例如,如果模板函数foo()位于foo.
h中,则相匹配的模板定义文件应该命名为foo.
cc或某些其他可识别的源文件扩展(.
C、.
c、.
cc、.
cpp、.
cxx或.
c++).
模板定义文件必须位于其中一个普通include目录或与定义文件相匹配的头文件的相同目录中.
7.
5.
2定义搜索路径另外一种可以替代用-I选项设定标准搜索路径的方法是:您可以用选项-ptidirectory指定模板定义文件的搜索目录.
多个-pti标志定义了多个搜索目录,即搜索路径.
如果您使用-pti目录,则编译器在该路径查找模板定义文件并忽略-I标志.
因为-pti目录标志将源文件的搜索规则复杂化,所以使用-I选项代替-pti目录选项.
7.
5.
3诊断有问题的搜索有时,编译器会生成一些莫名其妙的警告或错误消息,原因是它正在查找您并不打算进行编译的文件.
此问题通常是由于某个文件(如foo.
h)包含模板声明,而另一个文件(如foo.
cc)又隐式包含了该文件.
7-8《C++用户指南》2005年11月如果头文件foo.
h具有模板声明,则在默认情况下,编译器将搜索名为foo且带有C++文件扩展名(C、c、cc、cpp、.
cxx或c++)的文件.
如果找到这样的文件,编译器将自动把它包含进来.
有关这类搜索的详细信息,请参见第7-7页的第7.
5节"模板定义搜索".
如果您拥有文件foo.
cc,但是不想采用这种方式进行处理,则您有两个选择:更改.
h或.
cc文件的名称,以消除名称匹配.
通过指定-template=no%extdef选项禁止自动搜索模板定义文件.
然后必须在代码中显式包含所有模板定义,并且不能使用"独立定义"模型.
8-1第8章异常处理本章讨论了C++编译器如何实现异常处理.
更多信息请参见第11-2页的第11.
2节"在多线程程序中使用异常".
更多关于异常处理的信息,请参见BjarneStroustrup编著的《TheC++ProgrammingLanguage》第三版(Addison-Wesley,1997).
8.
1同步和异步异常异常处理设计用于仅支持同步异常,例如数组范围检查.
术语同步异常意味着异常仅可以来源于throw表达式.
C++标准支持具有终止模型的同步异常处理.
终止意味着异常抛出后,控制不会返回到抛出点.
异常处理没有设计用于直接处理诸如键盘中断等异步异常.
不过,如果小心处理,在出现异步事件时也可以进行异常处理.
例如,要用信号进行异常处理工作,您可以编写设置全局变量的信号处理程序,并创建另外一个例程来定期轮询该变量的值,当该变量值发生更改时抛出异常.
不能从信号处理程序抛出异常.
8.
2指定运行时错误有五个与异常有关的运行时错误消息:没有异常处理程序未预料到的异常抛出异常只能在处理程序中重新抛出在解开堆栈时,析构函数必须处理自身的异常内存不足8-2《C++用户指南》2005年1月在运行时检测到错误时,错误消息显示了当前异常的类型和这五个错误消息之一.
默认情况下,预定义的函数terminate()被调用,然后调用abort().
编译器使用异常规范中提供的信息来优化代码生成.
例如,禁止不抛出异常的函数表条目,而函数异常规范的运行时检查在任何可能的地方被消除.
8.
3禁用异常如果知道程序中不使用异常,则可以使用编译器选项-features=no%except来禁止生成支持异常处理的代码.
该选项的使用可以稍微减小代码的大小,并能加快代码的执行速度.
不过,用禁用的异常编译的文件链接到使用异常的文件时,在用禁用的异常编译的文件中的某些局部对象在发生异常时不会销毁.
默认情况下,编译器生成支持异常处理的代码.
通常都要启用异常,只有时间和空间的开销是考虑的重要因素时才禁止异常.
注–因为C++标准库dynamic_cast和默认运算符new需要异常,所以在标准模式(默认模式)中编译时不能关闭异常.
第8章异常处理8-38.
4使用运行时函数和预定义的异常标准头文件提供了C++标准中指定的类和与异常相关的函数.
仅在标准模式(编译器默认模式,或使用选项-compat=5)中编译时才可访问该头文件.
以下摘录了头文件声明.
标准类exception是由所选语言结构或C++标准库抛出的所有异常的基类.
类型exception的对象可以被构造、复制,在不生成异常销毁.
虚拟成员函数what()返回了描述异常的字符串.
//标准头文件namespacestd{classexception{exception()throw();exception(constexception&)throw();exception&operator=(constexception&)throw();virtual~exception()throw();virtualconstchar*what()constthrow();};classbad_exception:publicexception{.
.
.
};//意外的异常处理typedefvoid(*unexpected_handler)();unexpected_handlerset_unexpected(unexpected_handler)throw();voidunexpected();//终止处理typedefvoid(*terminate_handler)();terminate_handlerset_terminate(terminate_handler)throw();voidterminate();booluncaught_exception()throw();}8-4《C++用户指南》2005年1月为了与C++发行版本4.
2中所用的异常兼容,头文件也被提供用于标准模式.
该头文件允许转换到标准C++代码,并包含了不是标准C++部分的声明.
您可以按照开发计划的许可来更新代码以遵循C++标准(使用而不使用).
在兼容模式(-compat[=4])中,头文件不可用,并且头文件引用到C++发行版本4.
2提供的相同头文件.
头文件在这里不会重新生成.
8.
5将异常与信号和Setjmp/Longjmp混合只要setjmp/longjmp函数不交互,您就可以在发生异常的程序中使用这些函数.
使用异常和setjmp/longjmp的所有规则分别应用.
此外,只要在A处抛出和在B处捕获的异常具有相同的结果,从点A到点B的longjmp就是有效的.
具体来讲,您不必longjmp进或出try块或catch块(直接或间接),或longjmp超过自动变量或临时变量的初始化或不常用销毁.
不能从信号处理程序抛出异常.
8.
6生成具有异常的共享库永远不要使用具有包含C++代码的程序的-Bsymbolic,相反要使用链接程序映射文件.
使用-Bsymbolic时,在不同模块中的引用可以绑定到被假设为全局对象内容的不同副本中.
//头文件,用于转换#include#includeusingstd::exception;usingstd::bad_exception;usingstd::set_unexpected;usingstd::unexpected;usingstd::set_terminate;usingstd::terminate;typedefstd::exceptionxmsg;typedefstd::bad_exceptionxunexpected;typedefstd::bad_allocxalloc;第8章异常处理8-5异常机制依赖对地址的比较.
如果您具有某项内容的两个副本,它们的地址就不等同且异常机制可能失败,这是由于异常机制依赖对假设为唯一地址内容的比较.
使用dlopen打开共享库时,必须将RTLD_GLOBAL用于异常.
8-6《C++用户指南》2005年1月9-1第9章类型转换操作本章讨论C++标准中较新的类型转换操作符:const_cast、reinterpret_cast、static_cast和dynamic_cast.
类型转换可以将对象或值从一种类型转换为另一种类型.
这些类型转换操作比以前的类型转换操作更好控制.
dynamic_cast操作符提供了一种方法来检查到多态类的指针的实际类型.
您可以用文本编辑器来搜索所有新样式的类型转换(搜索_cast),而查找旧样式的类型转换需要语法分析.
否则,新的类型转换全部执行传统类型转换符号允许的类型转换子集.
例如,const_cast(v)可以写为(int*)v.
新的类型转换仅将各种可用的操作分类以更清楚地表示您的意图,并允许编译器提供更完善的检查.
类型转换操作符是始终启用的.
类型转换符不能被禁用.
9-2《C++用户指南》2005年1月9.
1const_cast表达式const_cast(v)可用于更改指针或引用的const或volatile限定符.
(在新样式的类型转换中,只有const_cast可以去掉const限定符.
)T必须是指针、引用或指向成员的指针的类型.
9.
2reinterpret_cast表达式reinterpret_cast(v)更改了表达式v值的解释.
该表达式可用于在指针和整数类型之间,在不相关的指针类型之间,在指向成员的指针类型之间,和在指向函数的指针类型之间转换类型.
reinterpret_cast操作符的用法可以具有未定义的或依赖于实现的结果.
以下几点描述了唯一确定的行为:指向数据对象或函数的指针(但不是指向成员的指针)可以转换为足够包含该指针的任何整数类型.
(long类型总是足以包含C++编译器支持的体系结构上的指针值.
)转换回原始类型时,指针值将与原始指针值相比较.
指向(非成员)函数的指针可以转换为指向不同(非成员)函数类型的指针.
如果转换回原始类型,指针值将与原始指针相比较.
假设新类型的对齐要求没有原始类型严格,则指向对象的指针可以转换为指向不同对象类型的指针.
转换回原始类型时,指针值将与原始指针值相比较.
如果使用重新解释的类型转换将"指向T1的指针"类型的表达式转换为"指向T2的指针"类型的表达式,则T1类型左值可以转换为"对T2的引用"类型.
classA{public:virtualvoidf();inti;};externconstvolatileint*cvip;externint*ip;voiduse_of_const_cast(){constAa1;const_cast(a1).
f();//去掉constip=const_cast(cvip);//去掉const和volatile}第9章类型转换操作9-3如果T1和T2都是函数类型或都是对象类型,则可以将"指向T1类型X成员的指针"类型右值显式转换为"指向T2类型Y成员的指针"类型右值.
在所有允许的情况下,空指针类型转换为不同的空指针类型后仍然是空指针.
reinterpret_cast操作符不能用于转换const,转换const要使用const_cast.
reinterpret_cast操作符不能用于转换指向位于同一类分层结构中不同类的指针,需使用静态或动态类型转换来实现这一目的.
(reinterpret_cast不执行所需的调整.
)这一点在以下示例中描述:9.
3static_cast表达式static_cast(v)将表达式v的值转换为T类型.
该表达式可用于任何隐式允许的转换类型.
此外,任何值都可以转换为void,并且如果类型转换与旧样式一样合法,则任何隐式转换都可以反向转换.
static_cast操作符不能用于转换const.
您可以使用static_cast来"向下"转换分层结构(从基到派生的指针或引用),但是不检查转换,因此结果有可能无法使用.
static_cast不能用于从虚拟基类向下转换.
classA{inta;public:A();};classB:publicA{intb,c;};voiduse_of_reinterpret_cast(){Aa1;longl=reinterpret_cast(&a1);A*ap=reinterpret_cast(l);//安全B*bp=reinterpret_cast(&a1);//不安全constAa2;ap=reinterpret_cast(&a2);//错误,没有const}classB{.
.
.
};classC:publicB{.
.
.
};enumE{first=1,second=2,third=3};voiduse_of_static_cast(C*c1){B*bp=c1;//隐式转换C*c2=static_cast(bp);//反向隐式转换inti=second;//隐式转换Ee=static_cast(i);//反向隐式转换}9-4《C++用户指南》2005年1月9.
4动态类型转换指向类的指针(或引用)可以实际指向(引用)从该类派生的任何类.
有时希望指向完全派生类的指针,或指向完整对象的某些其他子对象.
动态类型转换可以实现这些功能.
注–用兼容模式(-compat[=4])编译时,如果程序使用动态类型转换,您必须用-features=rtti编译.
动态类型转换将指向一个类T1的指针(或引用)转换到指向另一个类T2的指针(引用).
T1和T2必须位于同一分层结构,类必须是可访问的(经公共派生),并且转换必须要是明确的.
此外,除非转换是从派生的类到该派生类的一个基类,包括T1和T2的分层结构的最小部分必须是多态的(至少具有一个虚函数).
在表达式dynamic_cast(v)中,v是要被类型转换的表达式,而T是要转换到的类型.
T必须是完整类的类型(其中一个的定义是可视的)的指针或引用,或指向cvvoid、const、volatile或constvolatile的指针,其中cv是空字符串.
9.
4.
1将分层结构向上类型转换向上类型转换分层结构时,如果T指向(或引用)由v指向(引用)类型的基类,则该转换等价于static_cast(v).
9.
4.
2类型转换到void*如果T是void*,则该结果是指向完整对象的指针.
也就是说,v可能指向某些完整对象的其中一个基类.
在这种情况下,dynamic_cast(v)的结果如同将分层结构向下转换v到完整对象的类型,然后转换到void*.
类型转换到void*时,分层结构必须是多态的(具有虚函数).
9.
4.
3将分层结构向下或交叉类型转换向下或交叉类型转换分层结构时,分层结构必须是多态的(具有虚函数).
结果在运行时检查.
第9章类型转换操作9-5向下或交叉类型转换分层结构时,从v到T的转换并不总是可行的.
例如,尝试的转换可以是不明确的,T可能不可访问,或v不能指向(或引用)必要类型的对象.
如果运行时检查失败且T是指针类型,则类型转换表达式的值是T类型的空指针.
如果T是引用类型,什么都不会返回(C++中没有空引用),且标准异常std::bad_cast被抛出.
例如,此公共派生的示例成功:#include#include//为空classA{public:virtualvoidf();};classB{public:virtualvoidg();};classAB:publicvirtualA,publicB{};voidsimple_dynamic_casts(){ABab;B*bp=&ab;//无需类型转换A*ap=&ab;AB&abr=dynamic_cast(*bp);//成功ap=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);}9-6《C++用户指南》2005年1月然而该示例失败,原因是基类B是不可访问的.
如果在一个单独的基类中存在虚拟继承和多重继承,则实际动态类型转换必须能够识别出唯一的匹配.
如果匹配不唯一,则类型转换失败.
例如,假定有如下附加类定义:#include#include//为空#includeclassA{public:virtualvoidf(){}};classB{public:virtualvoidg(){}};classAB:publicvirtualA,privateB{};voidattempted_casts(){ABab;B*bp=(B*)&ab;//中断保护所必需的C样式类型转换A*ap=dynamic_cast(bp);//失败,B是不可访问的assert(ap==NULL);try{AB&abr=dynamic_cast(*bp);//失败,B是不可访问的}catch(conststd::bad_cast&){return;//此处捕获的失败引用类型转换}assert(0);//不应到此处}classAB_B:publicAB,publicB{};classAB_B__AB:publicAB_B,publicAB{};第9章类型转换操作9-7示例:dynamic_cast返回的空指针错误可用作两个代码体之间的条件,一个用于键入正确时处理类型转换,而另一个用于键入错误时停止类型转换.
在兼容模式(-compat[=4])中,如果运行时信息还未启用-features=rtti编译器选项,则编译器将dynamic_cast转换到static_cast并发出警告.
如果禁用异常,则编译器将dynamic_cast转换到static_cast并发出警告.
(如果发现转换在运行时无效,则需要抛出对引用类型的dynamic_cast异常.
关于异常的信息,请参见第8章.
动态转换需要比对应的设计模式慢,例如虚函数的转换.
请参见《DesignPatterns:ElementsofReusableObject-OrientedSoftware》,ErichGamma著(Addison-Wesley,1994).
voidcomplex_dynamic_casts(){AB_B__ABab_b__ab;A*ap=&ab_b__ab;//正确:找到唯一的静态AAB*abp=dynamic_cast(ap);//失败:不明确assert(abp==NULL);//静态错误:AB_B*ab_bp=(AB_B*)ap;//不是动态类型转换AB_B*ab_bp=dynamic_cast(ap);//动态转换正确assert(ab_bp!
=NULL);}voidusing_dynamic_cast(A*ap){if(AB*abp=dynamic_cast(ap)){//abp非空,//因此ap是指向AB对象的指针//继续并使用abpprocess_AB(abp);}else{//abp为空,//因此ap不是指向AB对象的指针//不使用abpprocess_not_AB(ap);}}9-8《C++用户指南》2005年1月10-1第10章改善程序性能采用编译器易于编译优化的方式编写函数,可以改善C++函数的性能.
有许多关于软件性能的书籍,尤其是关于C++.
例如,请参见《C++ProgrammingStyle》,TomCargill所著(Addison-Wesley,1992)、《WritingEfficientPrograms》,JonLouisBentley所著(Prentice-Hall,1982)、《EfficientC++:PerformanceProgrammingTechniques》,DovBulka和DavidMayhew所著(Addison-Wesley,2000)以及《EffectiveC++-50WaystoImproveYourProgramsandDesigns》,第二版,ScottMeyers所著(Addison-Wesley,1998).
本章不重复这些有价值的信息,而是讨论了主要影响C++编译器的那些性能技术.
10.
1避免临时对象C++函数经常会产生必须创建并销毁的隐式临时对象.
对于重要的类,临时对象的创建和销毁会占用很多处理时间和内存.
C++编译器消除了某些临时类,但是并不能消除所有的临时类.
您编写的函数要将临时对象的数目减少到理解程序所需的最小数目.
这些技术包括:使用显式变量而不使用隐式临时对象,以及使用引用变量而不使用值参数.
另外一种技术是实现和使用诸如+=这样的操作,而不实现和使用只包含+和=的操作.
例如,下面的第一行引入了a+b结果的临时对象,而第二行则不是.
Tx=a+b;Tx(a);x+=b;10-2《C++用户指南》2005年1月10.
2使用内联函数使用扩展内联而不使用正常调用时,对小而快速的函数的调用可以更小更快速.
反过来,如果使用扩展内联而不建立分支,则对又长又慢的函数的调用会更大更慢.
另外,只要函数定义更改,就必须重新编译对内联函数的所有调用.
因此,使用内联函数时要格外小心.
在期望更改函数定义而且重新编译所有调用方很费时间时,请不要使用内联函数.
否则,如果扩展函数内联的代码比调用函数的代码少,或使用函数内联时应用程序执行速度显著提高,那么可以使用内联函数.
编译器不能内联所有函数调用,因此使用最耗时的函数内联会需要某些源码的更改.
使用+w选项以了解何时不发生函数内联.
在以下情况中,编译器将不会内联函数:函数包含了复杂控制构造,例如循环、switch语句和try/catch语句.
这些函数很少多次执行复杂控制构造.
要内联这种函数,请将函数分割为两部分,里边的部分包含了复杂控制构造,而外边的部分决定了是否调用里边的部分.
即使编译器可以内联完整函数,从函数常用部分中分隔出不常用部分的这种技术也可以改善性能.
内联函数体又大又复杂.
因为对函数体内其他内联函数的调用,或因为隐式构造函数和析构函数调用(通常发生在派生类的构造函数和析构函数中),所以简单函数体可以非常复杂.
对于这种函数,内联扩展很少提供显著的性能改善,所以函数一般不内联.
内联函数调用的参数既大又复杂.
对于内联成员函数调用的对象是内联函数调用的自身这种情况,编译器特别敏感.
要内联具有复杂参数的函数,只需将函数参数计算到局部变量并将变量传递到函数.
10.
3使用默认运算符如果类定义不声明无参数的构造函数、复制构造函数、复制赋值运算符或析构函数,那么编译器将隐式声明它们.
它们都是调用的默认运算符.
类似C的结构具有这些默认运算符.
编译器生成默认运算符时,可以了解大量关于需要处理的工作和可以产生优良代码的工作.
这种代码通常比用户编写的代码的执行速度快,原因是编译器可以利用汇编级功能的优点,而编程人员则不能利用该功能的优点.
因此默认运算符执行所需的工作时,程序不能声明这些运算符的用户定义版本.
默认运算符是内联函数,因此内联函数不合适时不使用默认运算符(请参见上一节).
否则,默认运算符是合适的:用户编写的无参数构造函数仅为构造函数的基对象和成员变量调用无参数构造函数.
有效的基元类型具有"不执行任何操作"无参数构造函数.
用户编写的复制构造函数仅复制所有的基对象和成员变量.
第10章改善程序性能10-3用户编写的复制赋值运算符仅复制所有的基对象和成员变量.
用户编写的析构函数可以为空.
某些C++编程手册建议编写类的编程人员始终定义所有的运算符,以便该代码的任何读者都能了解该编程人员没有忘记考虑默认运算符的语义.
显然,该建议与以上讨论的优化有冲突.
这种冲突的解决方案是在代码中放置注释以表明类正使用默认运算符.
10.
4使用值类包括结构和联合在内的C++类通过值来传递和返回.
对于Plain-Old-Data(POD)类,C++编译器需要像C编译器一样传递结构.
这些类的对象是直接传递的.
对于用户定义复制构造函数的类的对象,编译器需要构造对象的副本,将指针传递到副本,并在返回后销毁副本.
这些类的对象是间接传递的.
编译器也可以选择介于这两个需求之间的类.
不过,该选择影响二进制的兼容性,因此编译器对每个类的选择必须保持一致.
对于大多数编译器,直接传递对象可以加快执行速度.
这种执行速度的改善对于小值类(例如复数和概率值)来说尤其明显.
有时为了改善程序执行效率,您可以设计更可能直接传递而不是间接传递的类.
在兼容模式(-compat[=4])中,如果类具有以下任何一条,则间接传递该类:用户定义的构造函数虚函数虚拟基类间接传递的基间接传递的非静态数据成员否则,类被直接传递.
在标准模式(默认模式)中,如果类具有以下任何一条,则间接传递该类:用户定义的复制构造函数用户定义的析构函数间接传递的基间接传递的非静态数据成员否则,类被直接传递.
10.
4.
1选择直接传递类尽可能直接传递类:只要可能,就使用默认构造函数,尤其是默认复制构造函数.
10-4《C++用户指南》2005年1月尽可能使用默认析构函数.
默认析构函数不是虚拟的,因此具有默认析构函数的类通常不是基类.
避免使用虚函数和虚拟基.
10.
4.
2在不同的处理器上直接传递类C++编译器直接传递的类(和联合)与C编译器传递结构(或联合)完全相同.
不过,C++结构和联合在不同的架构上进行不同的传递.
10.
5缓存成员变量访问成员变量是C++成员函数的通用操作.
编译器必须经常从内存通过this指针装入成员变量.
因为值通过指针装入,所以编译器有时不能决定何时执行第二次装入或以前装入的值是否仍然有效.
在这些情况下,编译器必须选择安全但缓慢的方法,在每次访问成员变量时重新装入成员变量.
如下所示,可以通过在局部变量中显式缓存成员变量的值来避免不必要的内存重新装入:声明局部变量并使用成员变量的值初始化该变量.
在函数中成员变量的位置使用局部变量.
如果局部变量变化,那么将局部变量的最终值赋值到成员变量.
不过,如果成员函数在该对象上调用另一个成员函数,那么该优化会产生不可预料的结果.
当值位于寄存器中时,这种优化最有效,而这种情况也与基元类型相同.
基于内存的值的优化也会很有效,因为减少的别名使编译器获得了更多的机会来进行优化.
表10-1在不同架构上结构和联合的传递架构描述SPARCV7/V8通过在调用方内分配存储并将指针传递到该存储,传递并返回结构和联合.
(也就是说,所有的结构和联合都通过引用传递.
)SPARCV9不超过16个字节(32个字节)的结构在寄存器中传递.
通过在调用方内分配存储并将指针传递到该存储,联合和所有其他结构将被传递并返回.
(也就是说,小的结构在寄存器中传递,而联合和大的结构通过引用传递.
)因此,小值类与基元类具有相同的传递效率.
x86平台结构和联合通过在堆栈上分配空间并将参数复制到堆栈上来传递.
通过在调用方的帧中分配临时对象并作为隐式第一个参数传递临时对象的地址,返回结构和联合.
第10章改善程序性能10-5如果成员变量经常通过引用(显式或隐式)来传递,那么优化可能并没什么效果.
有时,类的目标语义需要成员变量的显式缓存,例如在当前对象和其中一个成员函数参数之间有潜在别名时.
例如:会产生不可预料的结果,前提是调用时使用: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-6《C++用户指南》2005年1月11-1第11章生成多线程程序本章解释了如何生成多线程程序.
此外,还讨论了异常的使用,解释了如何在线程之间共享C++标准库对象,此外还描述了如何在多线程环境中使用传统(旧的)iostream.
关于多线程的更多信息,请参见《多线程编程指南》、《Tools.
h++用户指南》和《标准C++库用户指南》.
11.
1生成多线程程序C++编译器附带的所有库都是多线程安全的.
如果需要生成多线程应用程序,或者需要将应用程序链接到多线程库,那么您必须使用-mt选项来编译和链接程序.
该选项将-D_REENTRANT传递给预处理程序,并将-lthread以正确的顺序传递给ld.
在兼容模式(-compat[=4])下,-mt选项确保了libthread在libC之前被链接.
在标准模式(默认模式)下,-mt选项确保了libthread在libCrun之前被链接.
不要直接用-lthread链接应用程序,因为这将会引起libthread以错误的顺序链接.
以下示例显示了当编译和链接分开进行时,生成多线程应用程序的正确方法:以下示例显示了生成多线程应用程序的错误方法:example%CC-c-mtmyprog.
ccexample%CC-mtmyprog.
oexample%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.
1第11章生成多线程程序11-3pthread_cancel(3T)使用与异常一样的机制.
当一个线程被取消时,本地析构函数与清除例程将交叉执行,该清除例程被用户注册为pthread_cleanup_push().
在特定的清除例程注册之后,函数调用的本地对象在例程执行前就被销毁了.
11.
3在线程之间共享C++标准库对象C++标准库(libCstd-library=Cstd)是多线程安全的(有些语言环境例外),这样可以确保在多线程环境中库内部正常工作.
但是,您仍需要将各个线程之间要共享的库对象锁定起来.
请参见setlocale(3C)和attributes(5)手册页.
例如,如果实例化字符串,然后创建新的线程并使用引用将字符串传递给线程.
因为要在线程之间显示共享这个字符串对象,所以您必须锁定对于该字符串的写访问.
(库提供的用于完成该任务的工具在下文中会有描述.
)另一方面,如果通过值将字符串传递给新的线程,即使两个不同的线程通过RogueWave的"writeoncopy"技术共享表示,也不必担心锁定.
库将自动处理锁定.
只有当要使对象显式可用于多线程或在线程之间传递引用,以及使用全局或静态对象时,您才需要锁定.
下文描述了C++标准库内部使用的锁定(同步)机制,该机制用于确保在多线程下出现正确的行为.
_RWSTDMutex和_RWSTDGuard这两个同步类提供了实现多线程安全的机制.
_RWSTDMutex类在下列成员函数中提供了与平台无关的锁定机制:voidacquire()-自己锁定,或在锁定之前处于阻塞状态.
voidrelease()-自己解锁.
class_RWSTDMutex{public:_RWSTDMutex();~_RWSTDMutex();voidacquire();voidrelease();};11-4《C++用户指南》2005年1月_RWSTDGuard类是公用包装类,其中封装有_RWSTDMutex类的对象.
_RWSTDGuard对象尝试在其构造函数中获取封装的互斥(抛出std::exceptiononerror派生的::thread_error类型的异常),并在析构函数中释放互斥(析构函数从不会抛出异常).
另外,您可以使用宏_RWSTD_MT_GUARD(mutex)(以前的_STDGUARD)在多线程生成中有条件地创建_RWSTDGuard的对象.
该对象保护代码块的其余部分,并在该代码块中定义为可同时被多个线程执行.
在单线程生成中,宏扩展到空表达式中.
class_RWSTDGuard{public:_RWSTDGuard(_RWSTDMutex&);~_RWSTDGuard();};第11章生成多线程程序11-5以下示例说明了这些机制的使用.
11.
4在多线程环境中使用传统iostream本节描述了如何使用libC和libiostream库的iostream类在多线程环境中进行输入输出操作(I/O).
本节还提供了如何通过从iostream类派生来扩展库的功能.
不过本节并不是用C++编写多线程代码的指南.
#include////多个线程共享的整数.
//intI;////用以同步更新为I的互斥.
//_RWSTDMutexI_mutex;////每次对I递增1.
直接使用_RWSTDMutex.
//voidincrement_I(){I_mutex.
acquire();//锁定互斥.
I++;I_mutex.
release();//解锁互斥.
}////每次对I递减1.
使用_RWSTDGuard.
//voiddecrement_I(){_RWSTDGuardguard(I_mutex);//获取I_mutex的锁定.
--I;////调用处于保护状态的析构函数时,I的锁定被释放.
//}11-6《C++用户指南》2005年1月此处的讨论只适用于旧的iostream(libC和libiostream),但不适用于libCstd(即新的iostream,它是C++标准库的一部分).
iostream库允许其接口被多线程环境下的应用程序使用,而这些程序在运行支持的Solaris操作系统版本时使用多线程功能.
如果应用程序使用以前版本库的单线程功能,那么该应用程序不会受到影响.
如果库在线程环境中能正常工作,就将其定义为是多线程安全的.
通常,此处的"正确"意味着所有的公用函数都是可重入的.
iostream库提供了对多线程的保护,多线程尝试修改由多个线程共享的对象(即C++类的实例)状态.
不过,iostream对象的多线程安全范围限制在执行对象公用成员函数的周期内.
注–应用程序不会因为使用libC库中的多线程安全对象而自动保证是多线程安全的.
仅当应用程序在多线程环境中能按预期执行时,才将其定义为是多线程安全的.
11.
4.
1多线程安全的iostream库的组织多线程安全的iostream库的组织与其他版本的iostream库稍有不同.
库的输出接口指的是iostream类的公共的和受保护的成员函数以及可用的基类集合,这一点与其他版本的库相同,但各个版本的类分层结构是不同的.
详细信息,请参见第11-11页的第11.
4.
2节"对iostream库进行接口更改".
初始核心类以unsafe_前缀来重命名.
表11-1中列出了iostream软件包中的核心类.
每个多线程安全类都是从基类stream_MT派生的.
每个多线程安全类(除了streambuf外)也是从现有unsafe_基类派生的.
示例如下:表11-1iostream初始核心类类描述stream_MT多线程安全类的基类.
streambuf缓冲区的基类.
unsafe_ios该类包含各种流类通用的状态变量;例如,错误和格式化状态.
unsafe_istream该类支持streambuf检索到的字符序列的有格式和无格式的转换.
unsafe_ostream该类支持存储在streambuf中的字符序列的有格式和无格式的转换.
unsafe_iostream该类合并unsafe_istream和unsafe_ostream类用于双向操作.
classstreambuf:publicstream_MT{.
.
.
};classios:virtualpublicunsafe_ios,publicstream_MT{.
.
.
};classistream:virtualpublicios,publicunsafe_istream{.
.
.
};第11章生成多线程程序11-7stream_MT类提供了要求的互斥(mutex)锁定,以便每个iostream类都是多线程安全的.
此外还提供了用于动态启用和禁用锁定的功能,以便多线程安全的属性可以动态更改.
unsafe_类中包括I/O转换和缓冲区管理的基本功能,加到库中的多线程安全只限于派生类.
每个类的多线程安全版本包含了与unsafe_base类相同的受保护的和公共的成员函数.
多线程安全版本的类中每个成员函数都像包装器一样锁定对象,调用unsafe_base类中的相同函数,然后解锁对象.
注–streambuf类不是从不安全的类派生的.
streambuf的公共的和受保护的成员函数是可以通过锁定而重入的.
此外同时也提供了带有_unlocked后缀的不锁定版本.
11.
4.
1.
1公共转换例程iostream接口中增加了一组可重入的多线程安全的公共函数.
用户指定的缓冲区被作为每个函数的附加参数.
这些函数如下所述:表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空格.
返回值不保证指向用户提供缓冲区的开始部分.
char*form_r(char*buf,intbuflen,longnum,intwidth)返回由sprintf格式化字符串的指针,使用格式字符串format和其他剩余的参数.
缓冲区必须具有足够的空间以包含格式化的字符串.
11-8《C++用户指南》2005年1月注–用来确保与早期版本libC兼容的iostream库的公共转换例程(oct、hex、dec、chr和form)都不是多线程安全的.
11.
4.
1.
2使用多线程安全的libC库进行编译和链接生成使用libC库的iostream类的应用程序以在多线程环境中运行时,请使用-mt选项编译和链接应用程序的源代码.
该选项将-D_REENTRANT传递给预处理程序,并将-lthread传递给链接程序.
注–使用-mt(而不是-lthread)来链接libC和libthread.
该选项确保了库的正确链接顺序.
不正确的使用-lthread会引起应用程序工作不正常.
使用iostream类的单线程应用程序不需要特殊的编译器或链接程序选项.
默认情况下,编译器用libC库链接.
11.
4.
1.
3多线程安全的iostream限制iostream库的多线程安全的限制定义意味着大量使用iostream的编程用语在使用共享iostream对象的多线程环境中是不安全的.
检查错误状态要多线程安全,必须要对引起错误的I/O操作所在的临界区进行错误检查.
以下示例说明了如何检查错误:代码样例11-1检查错误状态#includeenumiostate{IOok,IOeof,IOfail};iostateread_number(istream&istr,int&num){stream_lockersl(istr,stream_locker::lock_now);istr>>num;if(istr.
eof())returnIOeof;if(istr.
fail())returnIOfail;returnIOok;}第11章生成多线程程序11-9在该示例中,stream_locker对象sl的构造函数锁定了istream对象istr.
在read_number终止时调用的析构函数sl解锁istr.
获取通过上次未格式化输入操作提取的字符要成为多线程安全的,必须在互斥使用istream对象的线程内,并在包括上次输入操作和gcount调用的执行周期内,调用gcount函数.
以下示例说明了对gcount的调用:在该示例中,stream_locker类的lock和unlock成员函数定义了程序中的互斥区域.
用户定义的I/O操作要成为多线程安全的,为用户定义类型定义的I/O操作必须锁定以定义临界区(这些类型涉及到单个操作的特定顺序).
以下示例说明了用户定义的I/O操作:代码样例11-2调用gcount#include#includevoidfetch_line(istream&istr,char*line,int&linecount){stream_lockersl(istr,stream_locker::lock_defer);sl.
lock();//锁定流istristr>>line;linecount=istr.
gcount();sl.
unlock();//解锁istr.
.
.
}代码样例11-3用户定义的I/O操作#include#includeclassmystream:publicistream{//其他定义.
.
.
intgetRecord(char*name,int&id,float&gpa);};intmystream::getRecord(char*name,int&id,float&gpa){stream_lockersl(this,stream_locker::lock_now);11-10《C++用户指南》2005年1月11.
4.
1.
4减少多线程安全类的性能开销在本版本的libC库中使用多线程安全类(即使是在单线程应用程序中),也会导致一定的性能开销.
但是您可以使用libC中的unsafe_类以避免此开销.
范围转换运算符可以用于执行基unsafe_类的成员函数,例如:注–unsafe_类不能在多线程应用程序中安全地使用.
您可以使cout和cin对象unsafe,然后使用正常操作来代替使用unsafe_类.
这会稍微降低性能.
以下示例说明了如何使用unsafecout和cin:iostream对象是多线程安全的时,将提供互斥锁定来保护对象的成员变量.
该锁定给仅在单线程环境中执行的应用程序增加了不必要的开销.
要提高性能,您可以动态切换iostream对象的多线程安全.
以下示例使iostream对象多线程不安全:*this>>name;*this>>id;*this>>gpa;returnthis->fail()==0;}cout.
unsafe_ostream::put('4');cin.
unsafe_istream::read(buf,len);代码样例11-4禁用多线程安全#include//禁用多线程安全cout.
set_safe_flag(stream_MT::unsafe_object);//禁用多线程安全cin.
set_safe_flag(stream_MT::unsafe_object);cout.
put('4');cin.
read(buf,len);代码样例11-5切换到多线程不安全fs.
set_safe_flag(stream_MT::unsafe_object);//禁用多线程安全.
.
.
.
执行各种i/o操作代码样例11-3用户定义的I/O操作(续)第11章生成多线程程序11-11您可以在iostream没有被线程共享的代码中安全地使用多线程不安全的流;例如,在只有一个线程的程序中,或在每个iostream都是线程专用的程序中.
如果将同步显式插入到程序中,那么也可以在线程共享iostream对象的环境中安全使用多线程不安全的iostreams.
以下示例说明了该技术:其中generic_lock和generic_unlock函数可以是使用诸如互斥、信号量或读取器/写入器锁定等基元的任何同步机制.
注–LibC提供的stream_locker类是实现这一目的的最佳机制.
更多信息请参见第11-15页的第11.
4.
5节"对象锁定".
11.
4.
2对iostream库进行接口更改本节讨论了使iostream库具有多线程安全而进行的接口更改.
11.
4.
2.
1新增类下表列出了增加到libC接口的新类.
代码样例11-6在多线程不安全的对象中使用同步generic_lock();fs.
set_safe_flag(stream_MT::unsafe_object);.
.
.
执行各种i/o操作generic_unlock();代码样例11-7新增类stream_MTstream_lockerunsafe_iosunsafe_istreamunsafe_ostreamunsafe_iostreamunsafe_fstreambaseunsafe_strstreambase11-12《C++用户指南》2005年1月11.
4.
2.
2新增类的分层结构下表列出了增加到iostream接口的新增类的分层结构.
11.
4.
2.
3新增函数下表列出了增加到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-9新增函数classstreambuf{public:intsgetc_unlocked();voidsgetn_unlocked(char*,int);intsnextc_unlocked();ntsbumpc_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();第11章生成多线程程序11-13char*gptr_unlocked();char*egptr_unlocked();char*pptr_unlocked();voidsetp_unlocked(char*,char*);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)代码样例11-9新增函数(续)11-14《C++用户指南》2005年1月11.
4.
3全局和静态数据多线程应用程序中的全局和静态数据不会在各个线程之间安全地共享.
尽管线程独立执行,但它们在进程中共享对全局和静态对象的访问.
如果一个线程修改了这种共享对象,那么进程中的其他线程将观察该更改,使得状态难以维持.
在C++中,类对象(类的实例)靠其成员变量的值来维持状态.
如果类对象被共享,那么该类对象将易于被其他线程更改.
多线程应用程序使用iostream库并包含iostream.
h时,默认情况下标准流cout、cin、cerr和clog被定义为全局共享对象.
因为iostream库是多线程安全的,所以该库将在执行iostream对象的成员函数时保护共享对象的状态不受其他线程的访问或更改.
不过,对象的多线程安全范围被限制在执行对象公用成员函数的周期内.
例如,在get缓冲区中获得下一个字符,并更新ThreadA中的缓冲区指针.
不过,如果ThreadA中的下一条指令是另一个get调用,那么libC库将不能保证按序返回下一个字符.
这是因为,例如ThreadB可能也会在ThreadA的两个get调用的间隙中执行get调用.
更多关于共享对象和多线程问题的处理策略,请参见第11-15页的第11.
4.
5节"对象锁定".
11.
4.
4序列执行通常当使用iostream对象时,I/O操作的序列必须是多线程安全的.
例如,如下所示代码:涉及到cout流对象的三个成员函数的执行.
由于cout是共享对象,所以必须像临界区那样独立执行序列,使其能在多线程环境中正常工作.
要独立对iostream类对象执行操作序列,您必须使用某些形式的锁定.
char*str_r(char*buf,intbuflen,constchar*format,intwidth=0);char*form_r(char*buf,intbuflen,constchar*format,.
.
.
)intc;cin.
get(c);cout#includevoidlock_example(fstream&fs){constintlen=128;charbuf[len];intoffset=48;stream_lockers_lock(fs,stream_locker::lock_now);打开文件11-16《C++用户指南》2005年1月在该示例中,stream_locker对象的构造函数定义了互斥区域的开始位置.
在互斥区域中每次只能执行一个线程.
从函数返回后调用的析构函数定义了互斥区域的结束位置.
Stream_locker对象确保了在文件中查找特定偏移和从文件中读取能够自动地同步执行,并且在初始的ThreadA读取文件之前,ThreadB无法更改文件偏移.
使用stream_locker对象的替代方法是显式定义互斥区域.
在以下示例中,要使I/O操作和随后的错误检查独立化,使用了vbstream_locker对象的lock和unlock成员函数调用.
更多信息请参见stream_locker(3CC4)手册页.
11.
4.
6多线程安全类您可以通过派生新的类来扩展或专用化iostream类.
如果由派生类实例化的对象被用于多线程环境中,那么这些类必须是多线程安全的.
派生多线程安全类时的注意事项包括:通过保护对象的内部状态避免多线程的修改,使得类对象成为多线程安全的.
要实现这一目的,请序列化对成员变量的公共访问,并使用互斥锁定来保护成员函数.
使用stream_locker对象,令多线程安全基类的成员函数调用序列独立化.
通过在stream_locker对象定义的临界区中使用streambuf的成员函数_unlocked,避免锁定开销.
fs.
seekg(offset,ios::beg);fs.
read(buf,len);}代码样例11-11令I/O操作和错误检查独立化{.
.
.
stream_lockerfile_lck(openfile_stream,stream_locker::lock_defer);.
.
.
.
file_lck.
lock();//锁定openfile_streamopenfile_stream#includefstream*fp;void*process_rtn(void*){//使用fp的子线程体.
.
.
}voidmulti_process(constchar*filename,intnumthreads){fp=newfstream(filename,ios::in);//创建fstream对象//创建线程之前.
//创建线程for(inti=0;i\n//其中标记是无符号字符的整数值.
//最多允许255个线程在该应用程序中运行//是任何可以打印的字符//因为标记是字符形式的整数值,//您需要使用od来查看输出文件,建议://od-cout.
file|more#include#include#include#include#includestructthread_args{char*filename;intthread_tag;};constintthread_bufsize=256;//每个线程的入口例程void*ThreadDuties(void*v){//获取该线程的参数thread_args*tt=(thread_args*)v;charibuf[thread_bufsize];//打开线程输入文件ifstreaminstr(tt->filename);stream_lockerlockout(cout,stream_locker::lock_defer);while(1){//每次读取一行第11章生成多线程程序11-19instr.
getline(ibuf,thread_bufsize-1,'\n');if(instr.
eof())break;//锁定cout流使得i/o操作独立化lockout.
lock();//标记行并发送到coutcoutthread_tag\n";exit(1);}intnum_threads=argc-1;inttotal_tags=0;//thread_id的数组thread_tcreated_threads[thread_bufsize];//线程入口例程的参数数组thread_argsthr_args[thread_bufsize];inti;for(i=0;iintmain(){cout来代替.
不能在兼容模式下使用.
在兼容模式下,必须在链接时显式请求complex库.
在标准模式下,complex库包括在libCstd中,并且是默认链接的.
标准模式没有complex.
h头文件.
在C++4.
2中,"complex"是类的名称,但是在标准C++中,"complex"是模板名称.
不可能提供可使旧的代码不加修改就可工作的typedef.
因此,为使用复数的4.
2版编写的代码需要某些简单的编辑,以便使用标准库.
例如,以下代码是为4.
2版编写的,并将在兼容模式下编译.
//文件prog2.
cc#includeintmain(){std::cout#includeintmain(){complexx(3,3),y(4,4);complexz=x*y;cout#includeusingstd::complex;intmain(){complexx(3,3),y(4,4);complexz=x*y;std::cout、和与编译器本身和libCrun紧密相关,且不能可靠替换.
库libCrun包含了大量编译器依赖的且不能替换的"helper"函数.
从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.
.
.
(编译)第12章使用库12-13编译期间,-library=no%Cstd选项防止搜索编译器本身版本的这些头文件所在的目录.
对于每个程序或库链接,使用-library=no%Cstd选项防止查找编译器本身的libCstd,-L选项指向替换库所在目录,-l选项指定替换库.
示例:或者,可以直接使用库的完整路径名称,忽略使用-L和-l选项.
例如:链接期间,-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)用作错误消息和调试器引用的文件名.
忽略文件的相关性信息时,编译器使用带后缀的名称.
example%CC-library=no%Cstd-L/opt/mycstd/lib-lmyCstd.
.
.
(链接)example%CC-library=no%Cstd/opt/mycstd/lib/libmyCstd.
a.
.
.
(链接)12-14《C++用户指南》2005年1月仅当出现在尖括号中且无需指定任何路径时,17种标准C头文件和32种标准C++头文件的两种格式才会发生名称重写.
如果使用引号来代替尖括号指定任何路径组件或其他某些头文件,就不会有重写发生.
下表说明了通常的情况.
如果编译器未找到header.
SUNWCCh,那么编译器将会重新搜索以查找#include指令提供的名称.
例如,如果给定指令#include,编译器就会尝试找到名为string.
SUNWCCh的文件.
如果搜索失败,编译器就会查找名为string的文件.
12.
7.
5.
1替换标准C++头文件由于在第12-13页的第12.
7.
5节"标准头文件实现"中描述的搜索算法,所以不必提供第12-12页的第12.
7.
3节"安装替换库"中所述替换头文件的SUNWCCh版本.
但是会遇到某些上文所述的问题.
如果是这样的话,建议为每个无后缀的头文件增加带有后缀.
SUNWCCh的符号链接.
也就是说,对于文件utility,您可以运行命令当编译器第一次查找utility.
SUNWCCh时,将会找到它,而不会和其他名为utility的文件或目录混淆.
12.
7.
5.
2替换标准C头文件不支持替换标准C头文件.
如果仍然希望提供标准头文件的自己的版本,那么建议按以下步骤操作:将所有替换头文件放置在一个目录中.
在目录中创建每个替换头文件的.
SUNWCCh符号链接.
通过在每次调用编译器时使用-I,搜索包含替换头文件的目录.
表12-3头文件搜索示例源码编译器搜索注释string.
SUNWCChC++字符串模板cstring.
SUNWCChCstring.
h的C++版本string.
h.
SUNWCChCstring.
hfcntl.
h不是标准C或C++头文件"string"string双引号,不是尖括号.
.
/string指定的路径example%ln-sutilityutility.
SUNWCCh第12章使用库12-15例如,假定您具有和的替换.
请将文件stdio.
h和cstdio放置在目录/myproject/myhdr中.
在该目录中,运行如下命令:每次编译时使用-I/myproject/mydir选项.
警告:如果要替换任何C头文件,就必须成对替换.
例如,如果要替换,就也必须替换.
替换头文件必须与被替换版本具有相同的效果.
这就是说,不同的运行时库(如libCrun、libC、libCstd、libc和librwtool)使用标准头文件中的定义来生成.
如果替换文件不匹配,那么程序不能工作.
example%ln-sstdio.
hstdio.
h.
SUNWCChexample%ln-scstdiocstdio.
SUNWCCh12-16《C++用户指南》2005年1月13-1第13章使用C++标准库当在默认(标准)模式下编译时,编译器可以访问C++标准指定的整个库.
库组件包括了标准模板库(STL)和以下组件.
字符串类数字类标准版本的流I/O类基本内存分配异常类运行时类型信息术语STL没有正式的定义,但是通常理解为包括容器、迭代器以及算法.
以下标准库头的子集可以认为包含了STL.
C++标准库(libCstd)基于版本2的RogueWave标准C++库.
该库仅在编译器的默认模式(-compat=5)下可用,使用-compat[=4]选项时不支持该库.
C++编译器也支持STLport的标准库实现版本4.
5.
3.
libCstd仍然是默认库,但STLport的产品只是可选的.
更多信息请参见第13-13页的第13.
3节"STLport".
如果需要使用自己的C++标准库版本代替编译器提供的版本,则可以通过指定-library=no%Cstd选项来实现.
替换与编译器一起发布的标准库是有风险的,不能保证产生预期的结果.
有关更多信息请参见第12-11页的第12.
7节"替换C++标准库".
13-2《C++用户指南》2005年1月关于标准库的详细信息,请参见《标准C++库用户指南》和《标准C++类库参考》.
本书前面的"阅读本书之前"第xxxii页的"访问SunStudio文档"一节中包含了访问该文档的信息.
关于C++标准库可用书籍的列表,请参见"阅读本书之前"中的第xxxv页的"其他公司出版的书籍"一节.
13.
1C++标准库头文件表13-1列出了完整标准库的头文件以及每个头的简要描述.
表13-1C++标准库头文件头文件描述操作容器的标准算法位的固定大小序列数字类型表示复数支持在端点增加和删除的序列预定义异常类文件的流I/O函数对象iostream操纵器iostream基类iostream类的前向声明基本流I/O功能输入I/O流遍历序列的类数字类型的属性排序的序列国际化支持带有键/值对的关联容器专用内存分配器基本内存分配和释放通用的数字操作输出I/O流第13章使用C++标准库13-313.
2C++标准库手册页表13-2列出了标准库中每个组件的可用文档.
支持在头部增加和在尾部删除的序列有唯一键值的关联容器将内存中的字符串用为源或接收器的流I/O支持在头部增加和删除的序列附加的标准异常类iostream的缓冲区类字符序列运行时类型标识比较操作符用于数字编程的值数组支持随机访问的序列表13-2C++标准库手册页手册页概述Algorithms在容器和序列上执行各种操作的通用算法Associative_Containers排序的容器Bidirectional_Iterators可以读取和写入,并且可以双向遍历容器的迭代器Containers标准模板库(STL)集合Forward_Iterators可以读取和写入的前移式迭代器Function_Objects定义了operator()的对象Heap_Operations查看make_heap、pop_heap、push_heap和sort_heap条目Input_Iterators只读的前移式迭代器Insert_Iterators允许迭代器向容器插入元素而非覆盖容器内元素的迭代器适配器Iterators集合遍历和修改的指针泛化.
表13-1C++标准库头文件(续)头文件描述13-4《C++用户指南》2005年1月Negators用于遍历谓词函数对象检测的函数适配器和函数对象OperatorsC++标准模板库输出的运算符Output_Iterators只写的前移式迭代器Predicates返回布尔(true/false)值或整型值的函数或函数对象Random_Access_Iterators可以读取、写入并随机访问容器的迭代器Sequences组织序列集合的容器Stream_Iterators包括允许直接在流上使用通用算法的ostreams和istreams的迭代器功能__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一个包含所有流都需要的通用函数的基类basic_iostream帮助格式化或者翻译由流缓冲区控制的字符序列basic_istream帮助读取或者翻译由流缓冲区控制的序列输入basic_istringstream支持从内存中的数组读取basic_string类对象basic_ofstream支持写入命名文件或者其他与文件描述符关联的设备basic_ostream帮助格式化或者写入由流缓冲区控制的序列输出表13-2C++标准库手册页(续)手册页概述第13章使用C++标准库13-5basic_ostringstream支持写入类对象basic_stringbasic_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代码转换侧面codecvt_byname一个包含以命名语言环境为基础的代码集转换分类工具的侧面collate一个字符串检验、比较和散列侧面collate_byname一个字符串检验、比较和散列侧面compare返回真或假的二元函数或函数对象complexC++复数库copy复制一定范围内的元素copy_backward复制一定范围内的元素表13-2C++标准库手册页(续)手册页概述13-6《C++用户指南》2005年1月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在序列中寻找上次出现的子序列find_first_of在序列中寻找在另一个序列中第一次出现的值find_if在满足特定谓词的序列中寻找第一次出现的值for_each将函数应用于范围内的每个元素fpos保持iostream类的位置信息front_insert_iterator用于在集合起始端插入条目的插入迭代器front_inserter用于在集合起始端插入条目的插入迭代器fstream支持对命名文件的读取和写入,或者与文件描述符关联的设备的读取和写入generate初始化一个具有由值产生器类产生的值的容器generate_n初始化一个具有由值产生器类产生的值的容器表13-2C++标准库手册页(续)手册页概述第13章使用C++标准库13-7get_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确定字符是字母还是数字isalpha确定字符是否为字母iscntrl确定字符是否为控制字符isdigit确定字符是否为十进制数字isgraph确定字符是否为图形字符islower确定字符是否为小写形式isprint确定字符是否可打印ispunct确定字符是否为标点符号isspace确定字符是否为空格istream帮助读取或者翻译由流缓冲区控制的序列输入istream_iterator具有istreams迭代器功能的流迭代器istreambuf_iterator从流缓冲区读取为其构造的连续字符表13-2C++标准库手册页(续)手册页概述13-8《C++用户指南》2005年1月istringstream支持读取内存中数组的basic_string类对象istrstream从内存中的数组读取字符isupper确定字符是否为大写形式isxdigit确定字符是否为十六进制数字iter_swap交换两个位置的值iterator基本的迭代器类iterator_traits返回有关迭代器的基本信息less如果第一个参数比第二个参数小就返回真的二元函数对象less_equal如果第一个参数小于或等于第二个参数就返回真的二元函数对象lexicographical_compare按照字典编排顺序来比较两个范围limits参考numeric_limitslist支持双向迭代器的序列locale包含多态侧面集的本地化类logical_and如果两个参数都为真就返回真的二元函数对象logical_not如果参数是假就返回真的一元函数对象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消息传送侧面表13-2C++标准库手册页(续)手册页概述第13章使用C++标准库13-9messages_byname消息传送侧面min查找并返回一对值中的最小值min_element查找一个范围中的最小值minus返回用第一个参数减去第二个参数所得到的结果mismatch比较来自两个序列的元素并且返回首次出现的两个不匹配元素modulus返回第一个参数除以第二个参数所得到的余数money_get输入的货币格式money_put输出的货币格式moneypunct货币标点格式moneypunct_byname货币标点格式multimap用关键字访问非关键字值的关联容器multiplies用于返回第一个参数与第二个参数相乘结果的二元函数对象.
multiset允许快速访问已保存关键字值的关联容器negate返回其参数负值的一元函数对象next_permutation生成以排序函数为基础的序列的连续置换not1对一元谓词函数对象进行求反操作的函数适配器not2对一元谓词函数对象进行求反操作的函数适配器not_equal_to如果第一个参数与第二个参数不相等就返回true的二元函数对象nth_element对集合重新排序,以便使在已排序顺序中比第n个元素小的排到第n个前面,比第n个元素大的就排到它后面.
num_get输入的数字格式num_put输出的数字格式numeric_limits表示标量类型信息的类numpunct数字标点格式numpunct_byname数字标点格式ofstream支持写入命名文件或者其他与文件描述符关联的设备ostream帮助格式化或者写入由流缓冲区控制的序列输出ostream_iterator流迭代器允许使用具有ostreams和istreams的迭代器ostreambuf_iterator向从其构造的流缓冲区对象写入连续的字符表13-2C++标准库手册页(续)手册页概述13-10《C++用户指南》2005年1月ostringstream支持写入类对象basic_stringostrstream写入一个在内存中的数组pair异类值对的模板partial_sort对实体集合排序的模板化算法partial_sort_copy对实体集合排序的模板化算法partial_sum计算一组值的连续部分的和partition将所有满足给定谓词的实体放置在不满足给定谓词的实体后面permutation生成以排序函数为基础的序列的连续置换plus用于返回第一个参数与第二个参数相加结果的二元函数对象pointer_to_binary_function与指向二元函数的指针相匹配的函数对象,替代binary_functionpointer_to_unary_function与指向函数的指针相匹配的函数对象类,替代unary_functionpop_heap从堆中移出最大的元素prev_permutation生成以排序函数为基础的序列的连续置换priority_queue像优先队列一样运行的容器适配器ptr_fun一个与指向某函数的指针对应的过载函数,替换一个函数push_heap将一个新元素放入堆queue像队列一样运行的容器适配器(先入先出)random_shuffle集合的随机混洗元素raw_storage_iterator使基于迭代器的算法能够将结果存入尚未初始化的内存中remove将所需元素移动到容器的前端,并返回一个说明所需元素序列的结束位置的迭代器remove_copy将所需元素移动到容器的前端,并返回一个说明所需元素序列的结束位置的迭代器remove_copy_if将所需元素移动到容器的前端,并返回一个说明所需元素序列的结束位置的迭代器remove_if将所需元素移动到容器的前端,并返回一个说明所需元素序列的结束位置的迭代器replace用新值替换集合中的元素表13-2C++标准库手册页(续)手册页概述第13章使用C++标准库13-11replace_copy用新值替换集合中的元素,并将修改过的序列移入结果replace_copy_if用新值替换集合中的元素,并将修改过的序列移入结果replace_if用新值替换集合中的元素return_temporary_buffer基于指针的基元,用于处理内存reverse反转集合中元素的顺序reverse_copy将集合中元素复制到新集合时反转它们的顺序reverse_iterator向后遍历集合的迭代器rotate将包含第一个元素到第middle-1个元素的部分与包含从中间到最后元素的部分交换rotate_copy将包含第一个元素到第middle-1个元素的部分与包含从中间到最后元素的部分交换search在值(这些值在元素状态时与标明范围内的值相等)的序列中查找子序列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>的typedef表13-2C++标准库手册页(续)手册页概述13-12《C++用户指南》2005年1月stringbuf将输入或者输出序列与任意字符序列关联stringstream支持读取或写入basic_string类对象,位置是内存中的数组strstream在内存中读取或者写入一个数组strstreambuf将输入序列或者输出序列与微型字符数组(其元素存储任意值)关联swap交换值swap_ranges将一个位置的值与在其他位置的值交换time_get输入的时间格式time_get_byname输入的时间格式,以命名语言环境为基础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对象关联表13-2C++标准库手册页(续)手册页概述第13章使用C++标准库13-1313.
3STLport如果要使用libCstd的另一个标准库,请使用标准库的STLport实现.
您可以使用以下编译器选项关闭libCstd并使用替代的STLport库:-library=stlport4更多信息请参见第A-41页的第A.
2.
48节"-library=l[,l.
.
.
]".
本发行版本包括称为libstlport.
a的静态归档和称为libstlport.
so的动态库.
决定是否使用STLport实现之前,请先考虑以下信息:wclog控制对流缓冲区的输出,该缓冲区与中声明的stderr对象关联wcout控制对流缓冲区的输出,该缓冲区与中声明的stdout对象关联wfilebuf将输入序列或输出序列与文件关联的类wfstream支持对命名文件的读取和写入,或者与文件描述符关联的设备的读取和写入wifstream支持从命名文件读取或者从其他与文件描述符关联的设备读取wios一个包含所有流都需要的通用函数的基类wistream帮助读取或者翻译由流缓冲区控制的序列输入wistringstream支持读取内存中数组的basic_string类对象wofstream支持写入命名文件或者其他与文件描述符关联的设备wostream帮助格式化或者写入由流缓冲区控制的序列输出wostringstream支持写入类对象basic_stringwstreambuf用于派生便于字符序列控制的各种流缓冲区的抽象基类wstringbasic_string、allocator>的typedefwstringbuf将输入或者输出序列与任意字符序列关联表13-2C++标准库手册页(续)手册页概述13-14《C++用户指南》2005年1月STLport是开放源代码产品,并不能保证不同发行版本之间的兼容性.
也就是说,使用后续版本的STLport编译,可能导致使用STLport4.
5.
3编译的应用程序中断.
使用后续版本的STLport编译的二进制文件可能无法与使用STLport4.
5.
3编译的二进制文件链接.
stlport4、Cstd和iostream库提供了自己的I/O流的实现.
使用-library指定其中的多个库,会导致不确定的程序行为.
编译器的后续发行版本可能不包括STLport4,只包括更新版本的STLport.
编译器选项-library=stlport4在后续发行版本中可能不能使用,但是可以使用引用更新STLport版本的选项来替换该选项.
Tools.
h++不支持STLport.
STLport和默认的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/zh/index.
html注–如果产品软件没有安装在默认目录中,请通过系统管理员获取系统中的相应路径.
第13章使用C++标准库13-15因为以下测试示例中的代码将库实现假定为不可移植,所以在该测试示例中不能使用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#includeclassstring{private:char*data;size_tsize;public://(这里的函数不相关)friendostream&operator>(istream&,string&);};第14章使用传统iostream库14-5在这种情况下,必须将插入运算符和提取运算符定义为友元,因为string类的数据部分是private.
以下是与string一起使用的重载operator>,按插入所用的方法将提取连贯起来.
例如:enumio_state{goodbit=0,eofbit=1,failbit=2,badbit=4,hardfail=0x80};cout>a>>b;第14章使用传统iostream库14-7该语句从标准输入获得两个值.
对其他重载运算符来讲,所用的提取器依赖于a和b的类型(如果a和b具有不同的类型,则使用两个不同的提取器.
)ios(3CC4)手册页中详细讨论了输入的格式以及如何控制输入格式.
通常,前导空白字符(空格、换行符、标签、换页等)被忽略.
14.
3.
3定义自己的提取运算符要输入新的类型时,如同重载输出的插入运算符,请重载输入的提取运算符.
类string定义了自己的提取运算符,如以下编码示例所示:get函数从输入流istr读取字符,并且在读取到maxline-1字符,或遇到新行或文件尾(不管哪个先发生)之前,将字符存储在holder中.
然后holder中的数据为空的终止.
最后,holder中的字符被复制到目标字符串.
按照约定,提取器转换第一个参数(此处是istream&istr)中的字符,然后将字符存储在第二个参数(通常是引用),最后返回第一个参数.
因为提取器会将输入值存储在第二个参数中,所以第二个参数必须是引用.
14.
3.
4使用char*提取器此处提及这个预定义的提取器是因为它可能产生问题.
使用方法如下:该提取器跳过前导空白,在遇到另一空白字符之前提取字符并将这些字符复制到x,最后完成具有终止空(0)字符的字符串.
因为输入会溢出给定的数组,所以要小心操作.
代码样例14-1string提取运算符istream&operator>>(istream&istr,string&input){constintmaxline=256;charholder[maxline];istr.
get(holder,maxline,'\n');input=holder;returnistr;}charx[50];cin>>x;14-8《C++用户指南》2005年1月您还必须确保指针指向了分配的存储.
例如,下面列出了一个常见的错误:因为没有告知存储输入数据的位置,所以会导致程序的终止.
14.
3.
5读取任何单一字符除了使用char提取器外,您还可以获得具有get成员函数任意一种形式的单一字符.
例如:注–与其他提取器不同的是char提取器不跳过前导空白.
以下方法可以只跳过空格,并在制表符、换行符或任何其他字符处停止:14.
3.
6二进制输入如果需要读取二进制值(如用成员函数write所写的值),那么您可以使用read成员函数.
以下示例显示了如何使用read成员函数来输入x的原始二进制形式(它是先前使用write的示例的反向操作).
char*p;//未初始化cin>>p;charc;cin.
get(c);//如果输入失败,不更改cintb;b=cin.
get();//如果输入失败,将b设置为EOFinta;do{a=cin.
get();}while(a=='');cin.
read((char*)&x,sizeof(x));第14章使用传统iostream库14-914.
3.
7查看输入您可以使用peek成员函数来查看流中的下一个字符,而不必提取该字符.
例如:14.
3.
8提取空白默认情况下,iostream提取器跳过前导空白.
您可以关闭跳过标志以防止发生跳过.
以下示例先从cin关闭了空白跳过,然后再重新打开:无论跳过是否启用,都可以使用iostream控制器ws从iostream删除前导空白.
以下示例显示了如何从iostreamistr删除前导空白:14.
3.
9处理输入错误按照约定,第一个参数为非零错误状态的提取器不能从输入流提取任何数据,且不能清除任何错误位.
失败的提取器至少应该设置一个错误位.
if(cin.
peek()!
=c)return0;cin.
unsetf(ios::skipws);//关闭空白跳过.
.
.
cin.
setf(ios::skipws);//重新打开istr>>ws;14-10《C++用户指南》2005年1月对于输出错误,您应该定期检查错误状态,并在发现非零状态时采取某些操作(诸如终止).
!
运算符用于测试iostream的错误状态.
例如,如果输入字母字符用于输入,以下代码就会产生输入错误:类ios具有用于错误处理的成员函数.
详细信息请参见手册页.
14.
3.
10使用具有stdio的iostream您可以与C++程序一起使用stdio,但是在程序内的相同标准流中混合iostream和stdio时会发生某些问题.
例如,如果同时写入stdout和cout,就会发生独立缓冲并产生未预料的结果.
如果您既从stdin输入也从cin输入,问题就会更严重,因为独立缓冲会使输入成为垃圾.
要消除标准输入、标准输出和标准错误中的这种问题,就请在执行输入或输出前使用以下指令:它将所有预定义的iostream与相应预定义的stdioFILE连接起来.
因为在预定义流作为连接的一部分成为无缓冲流时,性能会显著下降,所以该连接不是默认连接.
可以在应用到不同文件的同一程序中同时使用stdio和iostream.
也就是说,您可以使用stdio例程写入到stdout,也可以写入到附加到iostream的其他文件.
只要不再尝试从stdin读取,就可以打开stdioFILE用于输入,还可以从cin读取.
#include#includevoiderror(constchar*message){cerr>bad;if(!
cin)error("abortedduetoinputerror");cout>dec进行基于10的整型转换.
2ostr>hex进行基于16的整型转换.
6ostr>oct进行基于8的整型转换.
7istr>>ws找到非空白字符(留在istr中的字符)之前,提取空白字符(跳过空白).
8ostr>setbase(n)将转换基数设置为n(限于0、8、10和16).
9ostr>setw(n)调用ios::width(n).
将字段宽度设置为n.
10ostr>resetiosflags(i)根据i中的位设置,清除标志位向量.
14-16《C++用户指南》2005年1月要使用预定义的控制器,就必须在程序中包括文件iomanip.
h.
您可以定义自己的控制器.
控制器共有两个基本类型:无格式控制器,使用istream&、ostream&或ios&参数操作流并返回控制器的参数.
参数化控制器,使用istream&、ostream&或ios&参数及一个附加变量(参数)来操作流并返回该控制器的流参数.
14.
7.
1使用无格式控制器无格式控制器是具有如下功能的函数:执行到流的引用以某种方式操作流返回控制器的参数由于移位运算符使用了为iostream预定义的函数(指向它的指针),所以可以将函数放入输入或输出运算符的序列.
移位运算符调用函数,而不尝试读取或写入值.
将tab插入到ostream中tab控制器的示例如下所示:详细描述实现以下操作的方法:11ostr>setiosflags(i)根据i中的位设置,设置标志位向量.
12ostr>setfill(c)将填充字符(用于填充字段)设置为c.
13ostr>setprecision(n)将浮点精度设置为n个数字.
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;}//文件setfill.
cc#include#include//私有控制器staticios&sfill(ios&i,intf){i.
fill(f);returni;}//公共applicatorsmanip_intsetfill(intf){returnsmanip_int(sfill,f);}14-18《C++用户指南》2005年1月控制器.
它使用一个额外的参数.
在前一个编码示例中,它使用了额外的int参数.
由于未给这个控制器函数定义移位运算符,所以您无法将它放至输入或输出操作序列中.
相反,您必须使用辅助函数applicator.
applicator.
它调用该控制器.
applicator是全局函数,您会为它生成在头文件中可用的原型.
通常控制器是文件中的静态函数,该文件包含了applicator的源代码.
只有applicator可以调用该控制器,如果您将控制器设置为静态,就要使控制器名称始终位于全局地址空间之外.
在头文件iomanip.
h中定义了多个类.
每个类都保存一个控制器函数的地址和一个参数的值.
手册页manip(3CC4)中描述了iomanip类.
前一个示例使用了处理ios的smanip_int类.
因为该类和ios一起使用,所以也可以和istream与ostream一起使用.
前一示例还使用了类型为int的第二个参数.
applicator创建并返回类对象.
在前一编码示例中,类对象是smanip_int,其中包含了applicator的控制器和int参数.
iomanip.
h头文件定义了该类的移位运算符.
当applicator函数setfill出现在输入或输出操作的序列中时,applicator函数被调用并返回类.
移位运算符作用于该类,以调用具有参数值(存储在类中)的控制器函数.
在下例中,控制器print_hex:将输出流设置成十六进制模式.
将long值插入到流中.
恢复流的转换模式.
使用类omanip_long的原因是该编码示例仅用于输出,而且代码操作的是long而不是int:14.
8Strstream:数组的iostream请参见strstream(3CC4)手册页.
#include#includestaticostream&xfield(ostream&os,longv){longsave=os.
setf(ios::hex,ios::basefield);os>toFile.
rdbuf();example%man-s3CC4name第14章使用传统iostream库14-21表14-3iostream手册页概述手册页概述filebuf详细说明类filebuf的公用接口,该类从streambuf派生并专用于文件.
关于从类streambuf继承的功能的详细信息,请参见sbufpub(3CC4)和sbufprot(3CC4)手册页.
通过类fstream使用filebuf类.
fstream详细说明类ifstream、ofstream和fstream的专用成员函数,该类用于使用文件的istream、ostream和iostream的专用版本.
ios详细说明类ios的各个部分,该类作为iostream的基类.
该类也包含了所有流公共的状态数据.
ios.
intro介绍并概述了iostream.
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详细说明类strstreambuf的专用的公用接口,该类从streambuf派生并专用于处理字符数组.
关于从类streambuf继承的函数的详细信息,请参见sbufpub(3CC4)手册页.
stdiobuf包含了对类stdiobuf的最基本描述,该类从streambuf派生并专用于处理stdioFILE.
关于从类streambuf继承的函数详细信息,请参见sbufpub(3CC4)手册页.
strstream详细说明strstream的专用成员函数,这些函数由iostream所派生类的集合实现并专用于处理字符数组.
14-22《C++用户指南》2005年1月14.
12iostream术语iostream库描述了通常使用的术语,与一般编程的术语相类似,但却具有专门的含义.
下表定义了这些术语,与讨论iostream库时的用法相同.
表14-4iostream术语iostream术语定义缓冲该词具有两个含义,一个专用于iostream软件包,而另一个通常适用于输入和输出.
当特指iostream库时,缓冲是由类streambuf定义的类型的对象.
通常,缓冲是一个内存块,用于将字符高效传输到输出的输入.
对于已缓冲的I/O,缓冲已满或被强制刷新之前,字符的实际传输会延迟.
无缓冲的缓冲是指在其中没有以上所定义的通用缓冲的streambuf.
本章避免使用引用streambuf的术语缓冲.
但手册页和其他C++文档还用术语缓冲来表示streambuf.
提取从iostream获得输入的过程.
Fstream专用于文件的输入或输出流.
特指以courier字体打印时类iostream所派生的类.
插入发送输出到iostream中的过程.
iostream通常为输入或输出流.
iostream库该库的实现需要包括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字体打印时的特定类.
15-1第15章使用复数运算库复数是由实部和虚部组成的数字.
例如:在简并条件下,0+3i完全是虚数,通常写为3i,而5+0i完全是实数,通常写为5.
您可以使用complex数据类型来表示复数.
注–复数运算库(libcomplex)只用于兼容模式(-compat[=4]).
在标准模式(默认模式)中,C++标准库libCstd包括具有简单功能的复数类.
15.
1复数库复数运算库将复数数据类型实现为新的数据类型并提供:运算符数学库函数(为内建数字类型定义)扩展(用于允许复数输入和输出的iostream)错误处理机制复数还可以表示为绝对值(或幅度)和参数(或角度).
该库提供了在实部虚部(笛卡尔)表示和幅度角度(极性)表示间进行转换的函数.
数字复共轭的虚部中符号相反.
3.
2+4i1+3i1+2.
3i15-2《C++用户指南》2005年1月15.
1.
1使用复数库要使用复数库,请将头文件complex.
h包括在程序中,然后编译并用-library=complex选项进行链接.
15.
2类型complex复数运算库定义了一个类:complex类.
类complex的对象可以容纳一个单一复数.
复数被构造为两部分:实部虚部类complex的对象值是一对double值.
第一个值表示实部,第二个值表示虚部.
15.
2.
1类complex的构造函数complex有两个构造函数.
它们的定义是:如果不通过指定参数来声明复数变量,那么会使用第一个构造函数且变量被初始化,这时复数变量的两部分都为0.
下列示例创建了一个其实部和虚部均为0的复数变量.
您可以给定一个或两个参数.
无论是以上哪种情况,都将使用第二个构造函数.
只给定一个参数时,视为实部和虚部的值的参数被设置为0.
例如:classcomplex{doublere,im;};complex::complex(){re=0.
0;im=0.
0;}complex::complex(doubler,doublei=0.
0){re=r;im=i;}complexaComp;complexaComp(4.
533);第15章使用复数运算库15-3用下列值创建一个复数变量:如果给定了两个值,第一个值被视为实部的值,而第二个值被视为虚部的值.
例如:用下列值创建一个复数变量:您还可以使用复数运算库所提供的polar函数来创建复数(请参见第15-4页第15.
3节的"数学函数").
polar函数根据给定的极性坐标幅度和角度创建复数值.
complex类型没有析构函数.
15.
2.
2算法运算符复数运算库定义了所有基本的算法运算符.
具体来说,以下运算符按一般方法和普通的优先级工作:减运算符(-)具有其通常的二元和一元含义.
此外,您可以按通常的方法使用以下运算符:加法赋值运算符(+=)减法赋值运算符(-=)乘法赋值运算符(*=)除法赋值运算符(/=)但是,若将以上四个运算符用于表达式,则不产生任何值.
例如,下列表达式无法进行运算:您还可以按照常规含义使用等号(==)和不等号(!
=).
将运算表达式中的实数和复数混合时,C++使用复数运算符函数并将实数转换为复数.
4.
533+0icomplexaComp(8.
999,2.
333);8.
999+2.
333icomplexa,b;.
.
.
if((a+=2)==0)非法b=a*=b;//非法15-4《C++用户指南》2005年1月15.
3数学函数复数运算库提供了许多数学函数.
一些是专用于复数的,而其余的则是标准C数学库中函数的复数版本.
全部这些函数为每个可能的参数产生结果.
如果函数无法产生数学上可接受的结果,它就调用complex_error并返回一些适用的值.
特别的一点是,函数会尽量避免实际溢出,而改为调用具有消息的complex_error.
下表描述了复数运算库函数的提示.
注–sqrt和atan2函数的实现是按照C99csqrt附录G规范进行的.
表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)返回其参数的常用对数.
第15章使用复数运算库15-515.
4错误处理复数库具有以下对错误处理的定义:外部变量errno是C库中的全局错误状态.
errno可以执行标准头errno.
h中所列的值(请参见手册页perror(3)).
没有任何函数将errno设置为零,但是有许多函数会将它设置为其他值.
要分辨特定运算是否失败:1.
请在运算前将errno设置为零.
2.
测试运算.
函数complex_error引用c_exception的类型并被下列复数运算库函数调用:exploglog10双曲正弦双曲余弦complexpow(doubleb,constcomplexexp)complexpow(constcomplexb,intexp)complexpow(constcomplexb,doubleexp)complexpow(constcomplexb,constcomplexexp)使用两个参数:pow(b,exp).
这就使b具有了exp的幂.
complexsin(constcomplex)返回其参数的正弦.
complexsinh(constcomplex)返回其参数的双曲正弦.
complexsqrt(constcomplex)返回其参数的平方根.
complextan(constcomplex)返回其参数的正切.
complextanh(constcomplex)返回其参数的双曲正切.
externinterrno;classc_exception{.
.
.
};intcomplex_error(c_exception&);表15-2复数数学函数和三角函数(续)复数运算库函数描述15-6《C++用户指南》2005年1月complex_error的默认版本返回零值.
这个零值的返回意味着发生了默认的错误处理.
您可以提供自己的执行其他错误处理的替换函数complex_error.
手册页cplxerr(3CC4)中描述了错误处理.
手册页cplxtrig(3CC4)和cplxexp(3CC4)描述了默认的错误处理.
在下表中也对其进行了总结.
15.
5输入和输出如下列示例所示,复数运算库为复数成员提供了默认的提取程序和插入程序.
关于提取程序和插入程序的基本信息,请参见第14-2页第14.
2节的"iostream交互的基本结构"和第14-3页第14.
3.
1节的"使用iostream进行输出".
对输入来讲,复数提取程序>>从输入流提取一对数值(在圆括号中由逗号分隔)并将它们读入一个复数对象.
第一个值被视为实部的值,而第二个值被视为虚部的值.
例如,给定的声明和输入语句:以及输入(3.
45,5),x的值与3.
45+5.
0i的值相等.
对插入程序来讲反向为真.
给定的complexx(3.
45,5),cout>(istream&,complex&);//提取程序complexx;cin>>x;第15章使用复数运算库15-715.
6混合模式运算类型complex在设计上适用于混合模式表达式中的内建运算类型.
运算类型默认转换为类型complex,而且算法运算符和多数数学函数都有complex版本.
例如:其中表达式b+i是混合模式.
通过构造函数complex::complex(double,double=0)整型i被转换为类型complex,该整型首先是被转换为类型double.
结果是被doubley除,所以y也被转换为complex并使用了复数除法运算.
商是类型complex,所以会调用复数正弦例程,产生另一complex结果,等等.
但是,并非所有的数学运算符和转换都是暗示的(即使定义).
例如从数学角度,复数未较好排序,只能比较等式.
类似的,由于未明确定义概念,所以无法将类型complex自动转换为其他类型.
您可以指定是否需要实部、虚部或幅度.
15.
7效率complex类的设计主要侧重于效率.
最简单的函数声明为inline,用于消除函数调用的开销.
inti,j;doublex,y;complexa,b;a=sin((b+i)/y)+x/j;complexa,b;a==b;//正确a!
=b;//正确a=b;//错误:操作符>=不能应用于类型complexcomplexa;doublef(double);f(abs(a));//正确f(a);//错误:f(complex)不匹配15-8《C++用户指南》2005年1月在函数不同时就会提供函数的多个开销版本.
例如,pow函数的版本使用了类型double,int和complex的指数,因为前者的计算更简单.
当您包含complex.
h时,也会自动包含标准C数学库的头文件math.
h.
然后C++开销规则就会产生类似于下面的表达式效率评估:在该示例中,调用了标准数学函数sqrt(double),且将结果转换为类型complex,而不是先转换为类型complex再调用sqrt(complex).
该结果转向重载解决规则的外部,正好是您所希望的结果.
15.
8复数手册页复数运算库的剩余文档由下表所列的手册页组成:doublex;complexx=sqrt(x);表15-4类型complex的手册页手册页概述cplx.
intro(3CC4)对复数运算库的一般性介绍cartpol(3CC4)笛卡尔函数和极性函数cplxerr(3CC4)错误处理函数cplxexp(3CC4)指数、对数和平方根函数cplxops(3CC4)算法运算符函数cplxtrig(3CC4)三角函数16-1第16章生成库本章解释了如何生成您自己的库.
16.
1了解库库具有两点好处.
首先,它们提供了在多个应用程序间共享代码的方法.
如果您有要共享的代码,则可以创建一个具有该代码的库,并将该库链接到需要这些代码的应用程序.
其次,库提供了降低大型应用程序复杂性的方法.
这类应用程序可以将相对独立的部分生成为库并进行维护,因此减轻编程人员在其他部分工作的负担.
简单来说,生成一个库意味着创建.
o文件(通过使用-c选项编译代码)并使用CC命令将.
o文件组合到库中.
可以生成两种库,静态(归档)库和动态(共享)库.
对于静态(归档)库,在链接时库中的对象会链接到程序的可执行文件中.
只有库中这些应用程序所需的.
o文件被链接到可执行文件.
静态(归档)库的名称通常以.
a后缀结束.
对于动态(共享)库,库中的对象不会链接到程序的可执行文件,而是由链接程序告知可执行文件,程序要取决于库.
执行该程序时,系统会装入程序所需的动态库.
如果使用同一动态库的两个程序同时执行,那么操作系统在程序间共享这个动态库.
动态(共享)库的名称以.
so后缀结束.
动态链接共享库较静态链接归档库有多个优势:可执行文件较小.
在运行时,代码的有效部分可在程序间共享,这样就可以降低内存使用量.
库可以在运行时替换,无需重新链接应用程序.
(动态链接共享库的主要机制是使程序能够利用Solaris操作系统的多项改进的功能,而无需重新链接和分发程序.
)可以使用dlopen()函数调用在运行时装入共享库.
但动态库也具有一些缺点:16-2《C++用户指南》2005年1月运行时链接有执行时间成本.
使用动态库进行程序的分发可能会要求同时分发该程序所使用的库.
将共享库移动到一个不同的位置就可以阻止系统查找该库并执行程序.
(环境变量LD_LIBRARY_PATH可以帮助克服这个问题.
)16.
2生成静态(归档)库生成静态(归档)库的机制与生成可执行文件相似.
对象(.
o)集合文件可以使用CC的-xar选项合并到一个单一的库中.
您可以直接使用CC-xar来生成静态(归档)库,而无需使用ar命令.
C++语言通常要求编译器所维护的信息比传统.
o文件所提供的信息更多,尤其是模板实例.
-xar选项确保所有必要信息都包括在库中,其中包括模板实例.
由于make无法确定哪些是实际创建和引用的模板文件,所以在通常的编程环境下,您可能无法实现该操作.
如果没有所需的CC-xar,所引用的模板实例就可能不包括在库中.
例如:-xar标志使CC创建一个静态(归档)库.
-o指令用于命名新创建的库.
编译器检查命令行上的对象文件,交叉引用模板系统信息库中的对象文件,并将这些用户对象文件所需的模板(包括主对象文件本身)增加到归档中.
注–使用-xar标志来创建或更新现有归档.
不要用它来维护归档.
-xar选项等同于ar-cr.
最好在每个.
o文件中只具有一个函数.
如果您要链接归档,那么在需要该特定.
o文件中的符号时,归档的整个.
o文件都会被链接到应用程序.
每个.
o文件具有一个函数就可以确保只有这些应用程序所需的符号将与归档链接.
16.
3生成动态(共享)库动态(共享)库的生成方法与静态(归档)库相同,不同之处是您在命令行上使用的是-G而不是-xar.
%CC-cfoo.
cc#编译主文件,创建模板对象.
%CC-xar-ofoo.
afoo.
o#将所有对象收集到库中.
第16章生成库16-3您不应该直接使用ld.
使用静态库时,如果您使用的是模板,CC命令就可以确保模板系统信息库中所有必要的模板实例都包括在库中.
动态库中链接到应用程序的所有静态构造函数在执行main()之前调用,所有静态析构函数在main()退出之后调用.
如果使用dlopen()打开共享库,则所有的静态构造函数在dlopen()执行,而所有的静态析构函数在dlclose()执行.
您应该使用CC-G来生成动态库.
当您使用ld(链接编辑器)或cc(C编译器)来生成动态库时,异常可能不工作且库中所定义的全局变量不被初始化.
要生成动态(共享)库,就必须创建可重定位对象文件,做法是通过用CC的-Kpic(或-KPIC)选项来编译每个对象.
然后您就可以生成一个具有这些可重定位对象文件的动态库.
如果您遇到奇怪的链接失败,则可能忘记了用-Kpic或-KPIC编译部分对象.
要生成名为libfoo.
so的C++动态库(该库包含源文件lsrc1.
cc和lsrc2.
cc的对象),请键入:-G选项指定动态库的结构.
-o选项指定库的文件名.
-h选项指定共享库的名称.
-Kpic选项指定与位置无关的对象文件.
注–CC-G命令不将任何-l选项传递到ld.
如果您要使共享库具有对另一共享库的依存性,就必须在命令行上传递必需的-l选项.
例如,如果您要使共享库具有对libCrun.
so的依存性,就必须在命令行上传递-lCrun.
16.
4生成包含异常的共享库对于包含C++代码的程序,永远不要使用-Bsymbolic,而是要使用链接程序映射文件.
使用-Bsymbolic时,在不同模块中的引用可以绑定到被假设为全局对象内容的不同副本中.
异常机制依赖对地址的比较.
如果您具有某项内容的两个副本,它们的地址就不等同且异常机制可能失败,这是由于异常机制依赖对假设为唯一地址内容的比较.
使用dlopen()打开共享库时,必须将RTLD_GLOBAL用于异常才能工作.
%CC-G-olibfoo.
so-hlibfoo.
so-Kpiclsrc1.
cclsrc2.
cc16-4《C++用户指南》2005年1月16.
5生成专用的库在组织生成一个仅供内部使用的库时,可以使用不建议在一般情况下使用的选项来生成这个库.
具体来讲,库不需要兼容系统的应用程序二进制接口(ABI).
例如,可以使用-fast选项来编译库,以改善该库在已知架构上的性能.
同样地,可以使用-xregs=float选项来编译库以提高其性能.
16.
6生成公用的库在组织生成一个供其他公司使用的库时,库的管理、平台的一般性以及其他问题就变得尤为重要.
一个用于检验库是否为公用的简单测试就是询问应用程序编程人员是否可以轻松地重新编译该库.
公用库的生成应该与系统的应用程序二进制接口(ABI)兼容.
通常,这意味着应该避免任何特定于处理器的选项.
(例如,不要使用-fast或-xtarget.
)SPARCABI为应用程序保留了一些专用寄存器.
对V7和V8来讲,这些寄存器是%g2、%g3和%g4.
而对V9来讲,这些寄存器是%g2和%g3.
由于多数编译用于应用程序,所以在默认情况下,为了提高程序的性能,C++编译器将这些寄存器作为临时寄存器使用.
但是,对公用库中寄存器的使用通常不兼容于SPARCABI.
当生成公用库时,请使用-xregs=no%appl选项编译所有对象,以确保未使用应用程序寄存器.
16.
7生成具有CAPI的库如果要生成的库是用C++编写的,且可与C程序共同使用,那么就必须创建CAPI(应用程序编程接口).
要执行该操作,请先将所有已输出函数标记为extern"C".
注意,只有在全局函数中才能够完成该操作,在成员函数中不行.
如果C接口的库需要C++运行时的支持,同时您也用cc进行链接,则在使用该C接口的库时,还必须用libC(兼容模式)或libCrun(标准模式)链接应用程序.
(如果C接口的库不需要C++运行时支持,就没必要用libC或libCrun链接.
)归档库与共享库的链接步骤是不同的.
提供归档的C接口库时,必须提供如何使用该库的相关指令.
如果C接口的库是使用标准模式下的CC(默认)生成的,那么在使用该C接口的库时请将-lCrun增加到cc命令行.
如果C接口的库是使用兼容模式下的CC(-compat)生成的,那么在使用该C接口的库时请将-lC增加到cc命令行.
第16章生成库16-5提供共享的C接口库时,必须在生成库的时候创建对libC或libCrun的依存.
如果共享库具有正确的依存性,您就无需在使用该库时将-lC或-lCrun增加到命令行.
如果在兼容模式下(-compat)生成C接口库,那么在生成该库时请将-lC增加到CC命令行.
如果在标准模式下(默认)生成C接口库,那么在生成该库时请将-lCrun增加到CC命令行.
如果您要删除对C++运行库的任何依存性,就必须在库的源码中使用以下编码规则:不要使用任何形式的new或delete,除非您提供了自己的相应版本.
不要使用异常.
不要使用运行时类型信息(RTTI).
16.
8使用dlopen从C程序访问C++库要执行该操作,请在生成共享库时将-compat=4的-lC或-compat=5的-lCrun增加到命令行.
例如:如果共享库使用了异常且不具有对C++运行库的依存性,则C程序可能会出现无规律的行为.
注–使用dlopen()打开共享库时,RTLD_GLOBAL必须用于异常以便进行工作.
example%CC-G-compat=4.
.
.
-lCexample%CC-G-compat=5.
.
.
-lCrun16-6《C++用户指南》2005年1月第部分IV附录A-1附录AC++编译器选项本附录详细介绍了C++编译器的命令行选项.
描述的特性适用于除了说明以外的所有平台;基于SPARC系统的Solaris操作系统特有的特性标识为SPARC,基于x86系统的Solaris操作系统特有的特性标识为x86.
下表显示了典型选项语法格式的示例.
本手册前面的"阅读本书之前"中列出的印刷约定在这一节中用于描述单个选项.
圆括号、大括号、括号、管道字符和省略号是选项说明中使用的元字符,而不是选项自身的一部分.
表A-1选项语法格式示例语法格式示例-option-E-optionvalue-Ipathname-option=value-xunroll=4-optionvalue-ofilenameA-2《C++用户指南》2005年1月A.
1选项信息的结构为了帮助您查找信息,编译器选项说明被分为以下几个子节.
如果一个选项被其他选项取代或与其他选项一致,就请参见其他选项的说明以获取完整的详细信息.
A.
2选项参考A.
2.
1-386x86:与-xtarget=386相同.
该选项仅用于向后兼容.
表A-2选项子节子节内容选项定义紧跟在每个选项之后的简短定义.
(该类无标题.
)值如果选项具有一个或多个值,则本节将定义每个值.
默认如果选项具有主默认值或辅助默认值,则在此处进行声明.
如果未指定选项,则主默认值为有效选项值.
例如,如果未指定-compat,则默认值为-compat=5.
如果指定了选项但不给定任何值,则辅助默认值为有效选项值.
例如,如果-compat已指定但没有值,则默认值为-compat=4.
扩展如果选项具有宏扩展,则将在本节中显示.
示例如果要举例说明选项,则在此处给出所需示例.
交互如果选项与其他选项进行交互,则在此处讨论它们的关系.
警告如果有对选项使用的提醒(例如可能产生不期望的行为的操作),则在此处说明.
另请参见本节包含到其他选项或文档中更多的信息的引用.
"替换为""与.
.
.
相同"如果选项已废弃且已被其他选项替换,则在此处说明替换的选项.
以后的发行版本可能不支持这种方式描述的选项.
如果有两个选项具有相同的含义和目的,则在此处引用首选项.
例如,"与-xO相同"表示-xO为首选项.
附录AC++编译器选项A-3A.
2.
2-486x86:与-xtarget=486相同.
该选项仅用于向后兼容.
A.
2.
3-a与-xa相同.
A.
2.
4-Bbinding指定用于链接的库绑定是symbolic、dynamic(共享)还是static(非共享).
您可以在命令行上多次使用-B选项.
该选项被传递到链接程序ld.
注–很多系统库在Solaris64位编译环境中只能作为动态库使用.
因此,请勿将-Bstatic用作命令行的最后一个切换开关.
值binding必须是下列值之一:(在-B和binding值之间不允许有空格.
)默认如果未指定-B,则假定为-Bdynamic.
binding的值含义dynamic指定链接编辑器查找liblib.
so(共享)文件,如果未找到,则查找liblib.
a(静态,非共享)文件.
当链接需要共享库绑定时,请使用该选项.
static指定链接编辑器只查找liblib.
a(静态,非共享)文件.
当链接需要非共享库绑定时,请使用该选项.
符号如果可能,则强制在共享库中解析符号(即使符号已经在别处定义).
请参见ld(1)手册页.
A-4《C++用户指南》2005年1月交互要静态链接C++默认库,请使用-staticlib选项.
-Bstatic和-Bdynamic选项会影响默认提供的库链接.
要确保默认库是动态链接的,则最后所使用的-B应该是-Bdynamic.
在64位环境下,许多系统库只可以用作共享动态库.
其中包括libm.
so和libc.
so(而不提供libm.
a和libc.
a).
因此,在64位Solaris操作系统下,-Bstatic和-dn可能会产生链接错误.
这些情况下应用程序必须与动态库链接.
示例以下编译器命令链接了libfoo.
a(即使libfoo.
so存在),所有其他库都被动态链接:警告对于包含C++代码的程序,永远不要使用-Bsymbolic,而是要使用链接程序映射文件.
使用-Bsymbolic时,在不同模块中的引用可以绑定到被假设为全局对象的不同副本中.
异常机制依赖对地址的比较.
如果您具有某项内容的两个副本,它们的地址就不等同且异常机制可能失败,这是由于异常机制依赖对假设为唯一地址内容的比较.
如果您使用-Bbinding选项以不同的步骤进行编译和链接,就必须在链接步骤中包括该选项.
另请参见-nolib,-staticlib,ld(1)、第12-9页的第12.
5节"静态链接标准库"和《链接程序和库指南》A.
2.
5-c仅编译;产生对象文件.
o,但不进行链接.
该选项指定CC驱动程序禁止用ld进行链接,并为每个源文件生成一个.
o文件.
如果只在命令行上指定一个源文件,就可以用-o选项来显式命名对象文件.
example%CCa.
o-Bstatic-lfoo-Bdynamic附录AC++编译器选项A-5示例输入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.
7-compat[={4|5}]设置编译器的主发行版本兼容模式.
该选项控制__SUNPRO_CC_COMPAT和__cplusplus宏.
C++编译器有两个主要模式.
兼容模式接受4.
2编译器所定义的ARM语义和语言.
标准模式接受符合ANSI/ISO标准的构造.
由于ANSI/ISO标准在名称粉碎、虚函数表布局和其他ABI详细信息中强制进行显著的不兼容的更改,所以这两个模式是互相不兼容的.
这两个模式由以下值中所示的-compat选项进行区分.
值-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.
A-6《C++用户指南》2005年1月默认如果未指定-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的使用.
-Bsymbolic+efeatures=[no%]arraynewfeatures=[no%]explicitfeatures=[no%]namespacefeatures=[no%]rttilibrary=[no%]complexlibrary=[no%]libC-vdelx警告生成共享库时,不要使用-Bsymbolic.
另请参见《C++迁移指南》附录AC++编译器选项A-7A.
2.
8+d不扩展C++内联函数.
按照C++语言规则,C++内联函数是一个函数,对于该函数以下语句之一为真.
该函数的定义使用了inline关键字,该函数在类定义内部定义(不仅是声明)该函数是编译器生成的类成员函数按照C++语言规则,编译器可以选择是否将调用实际内联到内联函数.
C++编译器将调用内联到内联函数,除非:函数过于复杂,已选定+d选项,或者已选定-g选项示例默认情况下,编译器可以在以下代码示例中内联函数f()和memf2().
此外,该类具有编译器可以内联的由编译器生成的默认构造函数和析构函数.
当您使用+d时,编译器不会内联f()和C::mf2()(即构造函数和析构函数).
交互指定-g调试选项时,该选项自动打开.
-g0调试选项不打开+d.
+d选项对使用-xO4或-xO5时所执行的自动内联无效.
另请参见-g0、-ginlineintf(){return0;}//可以被内联classC{intmf1();//不内联,除非稍后出现内联定义intmf2(){return0;}//可以被内联};A-8《C++用户指南》2005年1月A.
2.
9-D[]name[=def]将宏符号name定义到预处理程序.
使用该选项与在源码开始位置包括#define指令等效.
您可以使用多个-D选项.
值下表显示了预定义的宏.
您可以在如#ifdef这样的预处理程序条件下使用这些值.
表A-3预定义的宏类型宏名称说明SPARC和x86__ARRAYNEW如果启用了操作符new和delete的"数组"形式,则定义__ARRAYNEW.
更多信息,请参见-features=[no%]arraynew.
_BOOL如果类型bool已启用,则定义_BOOL.
有关更多信息,请参见-features=[no%]bool.
__BUILTIN_VA_ARG_INCR用于varargs.
h、stdarg.
h和sys/varargs.
h.
中的关键字__builtin_alloca、__builtin_va_alist和__builtin_va_arg_incr.
__cplusplus__DATE____FILE____LINE____STDC__设置为0(零)__sunsun请参见交互.
__SUNPRO_CC=0x580__SUNPRO_CC的值表示编译器的发行版本编号__SUNPRO_CC_COMPAT=4或__SUNPRO_CC_COMPAT=5请参见第A-5页的第A.
2.
7节"-compat[={4|5}]"(SPARC)__SUN_PREFETCH=1__SVR4__TIME__附录AC++编译器选项A-9如果您不使用=def,则name被定义为1.
交互使用+p,则不定义sun、unix、sparc和i386.
另请参见-UA.
2.
10-d{y|n}允许或不允许整个可执行文件的动态库.
该选项被传递到ld.
该选项只能在命令行出现一次.
__'uname–s'_'uname–-r\'在-D__SunOS_5_7和-D__SunOS_5_8中时,uname-s是uname-s的输出,而uname-r是具有无效字符的uname-r的输出,如用下划线替换的句号(.
).
__unixunix请参见交互.
(SPARC)__sparcsparc请参见交互.
(SPARC)v9__sparcv9只限于64位编译模式x86__i386i386请参见交互.
UNIX_WCHAR_T表A-3预定义的宏(续)类型宏名称说明A-10《C++用户指南》2005年1月值默认如果未指定-d选项,则假定为-dy.
交互在64位环境下,许多系统库只可以用作共享动态库.
其中包括libm.
so和libc.
so(而不提供libm.
a和libc.
a).
因此,在64位Solaris操作系统下,-Bstatic和-dn可能会产生链接错误.
这些情况下应用程序必须与动态库链接.
警告如果将此选项与动态库结合使用,将导致致命错误.
大多数系统库仅作为动态库时可用.
另请参见ld(1)、《链接程序和库指南》A.
2.
11-dalign-dalign等价于-xmemalign=8s.
有关更多信息,请参见第A-104页的第A.
2.
139节"-xmemalign=ab".
警告如果您用-dalign编译一个程序单元,就要使用-dalign来编辑程序的所有单元,否则会产生意外的结果.
值含义-dy在链接编辑器中指定动态链接.
-dn在链接编辑器中指定静态链接.
附录AC++编译器选项A-11A.
2.
12-dryrun显示但不编译驱动程序所生成的子命令.
该选项指示驱动程序CC显示但不执行编译驱动程序所构造的子命令.
A.
2.
13-E对源文件运行预处理程序但不进行编译.
指示CC驱动程序仅在C++源文件上运行预处理程序,并将结果发送到stdout(标准输出).
不执行任何编译,不生成任何.
o文件.
该选项使预处理程序输入行号信息包括在输出中.
示例该选项用于确定预处理程序所进行的更改.
例如,以下程序foo.
cc生成了代码样例A-2中所示的输出.
代码样例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);intmain(){intx;x=power(2,10);}A-12《C++用户指南》2005年1月警告使用模板时,从该选项的输出不支持作为C++编译器的输入.
另请参见-PA.
2.
14+e{0|1}在兼容模式(-compat[=4])下控制虚拟表的生成.
在标准模式下(默认模式)无效并被忽略.
值+e选项可以具有以下值.
交互使用该选项进行编译时,也可以使用-features=no%except选项.
否则,编译器会为用于异常处理的内部类型生成虚拟表.
如果模板类具有虚函数,就可能无法确保编译器生成全部所需的虚拟表而不复制这些表.
另请参见《C++迁移指南》A.
2.
15-erroff[=t]该命令禁止出现C++编译器警告消息,而不会影响错误消息.
该选项适用于所有警告消息,无论-errwarn是否指定这些消息以导致非零退出状态.
值含义0禁止虚拟表的生成并创建对所需虚拟表的外部引用.
1为所有定义的具有虚函数的类创建虚拟表.
附录AC++编译器选项A-13值t是一个以逗号分隔的列表,该列表包括以下各项中的一个或多个:tag、no%tag、%all、%none.
顺序是很重要的;例如%all,no%tag禁止了除tag以外的所有警告消息.
下表列出了-erroff值:默认默认为-erroff=%none.
指定-erroff与指定-erroff=%all相同.
示例例如,-erroff=tag会禁止由该标记指定的警告消息.
另一方面,-erroff=%all,no%tag会禁止除tag指定的消息之外的所有警告消息.
使用-errtags=yes选项可以显示警告消息的标记.
警告使用-erroff选项只可以禁止来自C++编译器前端的警告消息,该警告消息会在使用-errtags选项时显示一个标记.
另请参见-errtags、-errwarnA.
2.
16-errtags[=a]显示C++编译器前端每个警告消息的消息标记,使用-erroff选项可以禁止警告消息,而使用-errwarn选项则可能产生致命的错误.
表A-4-erroff值值含义tag禁止由该tag指定的警告消息.
使用-errtags=yes选项可以显示消息的标记.
no%tag启用由该tag指定的警告消息.
%all禁止所有警告消息.
%none启用所有警告消息(默认).
A-14《C++用户指南》2005年1月值和默认a可以是yes或no.
默认为-errtags=no.
指定-errtags与指定-errtags=yes相同.
警告来自C++编译器驱动程序和编译系统其他组件的消息没有错误标记,因此无法使用-erroff来禁止,使用-errwarn也不会产生致命错误.
另请参见-erroff、-errwarnA.
2.
17-errwarn[=t]利用-errwarn来使C++编译器在给定警告消息处于失败的状态下退出.
值t是一个以逗号分隔的列表,该列表包括以下各项中的一个或多个:tag、no%tag、%all、%none.
顺序很重要,例如如果出现除tag之外的任何警告,%all,no%tag会使cc带致命状态退出.
下表详细列出了-errwarn值:表A-5-errwarn值值含义tag如果该tag指定的消息以警告消息的形式出现,就会使CC带致命状态退出.
如果未发出tag,则不会产生这种情况.
no%tag如果tag指定的消息只以警告消息的形式出现,就要防止CC带致命状态退出.
如果tag指定的消息未出现,则不会产生这种情况.
为了避免在发生警告消息时导致cc带致命状态退出,就要使用该选项来还原以前用tag或%all指定的警告消息.
%all如果发生任何警告消息,就会使CC带致命状态退出.
%all可以后跟no%tag以避免该行为的特定警告消息.
%none防止任何引起CC带致命状态退出的警告消息(该发出任何警告消息时).
附录AC++编译器选项A-15默认默认为-errwarn=%none.
如果单独指定-errwarn,就等效于-errwarn=%all.
警告-errwarn选项只可以指定来自C++编译器前端的警告消息来使编译器在失败状态下退出,其中的警告消息会在使用-errtags选项时显示标记.
因为编译器错误检查的增强和功能的增加,C++编译器生成的警告消息在不同发行版本中各有不同.
使用-errwarn=%all进行编译而不会产生错误的代码,在编译器下一个发行版本中编译时也可能出现错误.
另请参见-erroff、-errtagsA.
2.
18-fast此选项是一个宏,可有效用作调节可执行程序以达到最大运行时性能的起始点.
-fast是一个宏,可随编译器发行版本的升级而更改,并能扩展为目标平台特定的选项.
使用-#选项或-xdryrun检查-fast的扩展选项,并将-fast的相应选项合并到现行的可执行程序调节进程中.
该选项是一个宏,选择编译选项的组合用于在编译代码的机器上优化执行速度.
扩展该选项通过扩展到以下编译选项,为大量应用程序提供了几乎最高的性能.
表A-6-fast扩展选项SPARCx86-fnsXX-fsimple=2X--ftrap=%noneXX-nofstore-X-xlibmilXX-xlibmoptXXA-16《C++用户指南》2005年1月交互-fast宏扩展到可能影响其他指定选项的编译选项中.
例如,在以下命令中,-fast宏的扩展包括了将-xarch还原为32位架构选项的-xtarget=native.
错误:正确:查看每个选项的描述以确定可能的交互操作.
代码生成选项、优化级别、内建函数的优化和内联模板文件的使用可以用后续选项来覆盖(请参见示例).
指定的优化级别将覆盖以前所设置的优化级别.
-fast选项包括-fns-ftrap=%none;即,该选项关闭了所有捕获.
示例以下编译器命令生成了-xO3的优化级别.
以下编译器命令产生了-xO5的优化级别.
-xmemalignX--xO5XX-xtarget=nativeXX-xbuiltin=%allXXexample%CC-xarch=v9-fasttest.
ccexample%CC-fast-xarch=v9test.
ccexample%CC-fast-xO3example%CC-xO3-fast表A-6-fast扩展(续)选项SPARCx86附录AC++编译器选项A-17警告如果单独进行编译和链接,-fast选项就必须出现在编译命令和链接命令中.
-fast选项所编译的代码不可移植.
例如,在UltraSPARCII系统中无法执行在UltraSPARCIII系统中用以下命令生成的二进制文件.
不要将该选项用于依赖IEEE标准浮点运算的程序,否则可能会产生不同的数字结果、过早的程序终止或意外的SIGFPE信号.
在以前的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++语言功能.
example%CC-fasttest.
ccA-18《C++用户指南》2005年1月值在兼容模式(-compat[=4])和标准模式(默认模式)下a都可以具有以下值:表A-7兼容模式和标准模式的-features值a的值含义%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.
[no%]except[不]允许C++异常.
C++异常被禁用时(即-features=no%except),接受但忽略了函数的抛出规范,编译器不生成异常代码.
注意,通常保留关键字try、throw和catch.
请参见第8-2页的第8.
3节"禁用异常".
默认为except.
[no%]export[不]识别关键字export.
在兼容模式下默认为no%export,在标准模式下默认为export.
[no%]extensions[不]允许其他C++编译器通常接受的非标准代码.
关于使用-features=extensions选项时编译器接受的无效代码的说明,请参见第4章.
默认为no%extensions.
[no%]iddollar[不]允许$符号作为非初始化标识符字符.
默认为no%iddollar.
[no%]localfor[不]在for语句中使用新的局部作用域规则.
在兼容模式下默认为no%localfor,在标准模式下默认为localfor.
[no%]mutable[不]识别关键字mutable.
在兼容模式下默认为no%mutable,在标准模式下默认为mutable.
附录AC++编译器选项A-19在标准模式(默认模式)下,a可以具有以下附加值:[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-8仅用于标准模式的-features值a的值含义[no%]strictdestrorder[不]遵循由C++标准指定的要求,该要求关于具有静态存储持续时间对象的析构顺序.
默认为strictdestrorder.
[no%]tmplife[不]清除由位于全表达式结尾处的表达式(在ANSI/ISOC++标准中定义)创建的临时对象.
(-features=no%tmplife生效时,多数临时对象会在块的结尾处清除.
)默认为no%tmplife.
表A-7兼容模式和标准模式的-features值(续)a的值含义A-20《C++用户指南》2005年1月在兼容模式(-compat[=4])下,a可以具有以下附加值.
注–[no%]castop设置可以与为C++4.
2编译器所编写的makefiles兼容,但不影响编译器版本5.
0、5.
1、5.
2和5.
3.
新型的类型转换(const_cast、dynamic_cast、reinterpret_cast和static_cast)始终会被识别但无法被禁用.
默认如果未指定-features,则做出以下假定:兼容模式(-compat[=4])标准模式(默认模式)交互该选项会累积而不覆盖.
表A-9仅用于兼容模式的-features值a的值含义[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).
要使用dynamic_cast和typeid运算符,就必须启用RTTI.
默认为no%rtti.
对于-compat=4mode,默认值为no%rtti.
否则,默认值为-features=rtti,并且不允许使用选项-features=no%rtti.
-features=%none,anachronisms,except,split_init,transitions-features=%all,no%iddollar,no%extensions,no%tmplife附录AC++编译器选项A-21在标准模式(默认)中以下选项与标准库和头文件不兼容: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将初始化函数的分离部分转换到独立的函数中.
另请参见第4章和《C++迁移指南》A.
2.
20-filt[=filter[,filter.
.
.
]]控制编译器通常应用于链接程序和编译器错误消息的过滤.
A-22《C++用户指南》2005年1月值filter必须是下列值之一:默认如果未指定-filt选项或指定没有任何值的-filt,那么编译器假定-filt=%all.
示例以下示例显示了使用-filt选项编译该代码的效果.
表A-10-filt值filter的值含义[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_demo.
ccclasstype{public:virtual~type();//未提供定义};intmain(){typet;}附录AC++编译器选项A-23编译代码时如果不使用-filt选项,编译器就会假定-filt=errors,names,returns,stdlib并显示标准输出.
以下命令禁止还原C++粉碎链接程序名称,并禁止链接程序错误的C++解释.
现在考虑以下代码:以下是指定-filt=no%stdlib时的输出内容:以下是指定-filt=stdlib时的输出内容:example%CCfilt_demo.
ccUndefinedfirstreferencedsymbolinfiletype::~type()filt_demo.
otype::__vtblfilt_demo.
o[提示:试图检查是否已定义了类的类型的第一个非内联、非纯虚函数]ld:fatal:Symbolreferencingerrors.
Nooutputwrittentoa.
outexample%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);//此处出错}Error:Cannotusestd::list>toinitializestd::basic_string,std::allocator>.
Error:Cannotusestd::listtoinitializestd::string.
A-24《C++用户指南》2005年1月交互当您指定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-fnonstd使硬件自陷可用于浮点溢出,除以零,并可用于无效运算异常.
产生的结果被转换为SIGFPE信号,如果程序没有SIGFPE处理程序,它就会终止并转储内存(除非将核心转储大小限制到零).
SPARC:此外,-fnonstd还选择SPARC非标准浮点.
默认如果未指定-fnonstd,则IEEE754浮点算术异常不终止程序并逐步下溢.
扩展x86:-fnonstd扩展到-ftrap=common.
SPARC:-fnonstd扩展到-fns-ftrap=common.
另请参见-fns、-ftrap=common、《数值计算指南》.
A.
2.
23-fns[={yes|no}]SPARC:启用/禁用SPARC的非标准浮点模式.
-fns=yes(或-fns)会在程序开始执行时启用非标准浮点模式.
附录AC++编译器选项A-25该选项提供了一种切换非标准或标准浮点模式的方法,后跟包括-fns的某些其他宏选项(如-fast).
在某些SPARC设备上,非标准浮点模式会禁用"渐进下溢",这会导致微小的结果被刷新为零而不是产生低于正常的值,还会导致低于正常的操作数被默置为零.
在不支持硬件逐步下溢和低于正常的数的SPARC设备上,-fns=yes(或-fns)可以显著提高某些程序的性能.
(x86)选择SSE刷新为零模式以及(如果可用)反向规格数为零模式.
此选项导致将次正规结果刷新为零.
如果可用的话,此选项还导致将次正规操作数视为零.
此选项未采用SSE或SSE2指令集的传统x86浮点运算.
值-fns选项可以具有以下值.
默认如果未指定-fns,则不自动启用非标准浮点模式.
标准IEEE754浮点计算发生(即渐进下溢).
如果仅指定了-fns,则假定-fns=yes.
示例在以下示例中,-fast扩展到了多个选项,其中一个是-fns=yes,即选择非标准浮点模式.
随后-fns=no选项覆盖初始设置,并选择浮点模式.
警告非标准模式启动时,浮点运算可以产生不符合IEEE754标准要求的结果.
表A-11-fns值值含义是选择非标准浮点模式否选择标准浮点模式example%CCfoo.
cc-fast-fns=noA-26《C++用户指南》2005年1月如果先使用-fns选项编译一个例程,就要使用-fns选项来编译程序的所有例程;否则,就可能获得意外的结果.
该选项仅在SPARC设备上有效,并且仅在编译主程序时才能有效使用.
在x86设备上,此选项被忽略.
在程序中出现通常由IEEE浮点自陷处理程序管理的浮点错误时,使用-fns=yes(或-fns)选项可能会生成以下消息:另请参见《数值计算指南》、ieee_sun(3M)A.
2.
24-fprecision=px86:设置非默认的浮点精度模式.
-fprecision选项设置浮点控制字中的舍入精度模式位.
这些位控制基本算术运算(加、减、乘、除和平方根)结果的舍入精度.
值p必须是下列值之一:如果p为single或double,则该选项会使舍入精度模式在程序开始执行时分别设置为single或double精度.
如果p是未使用的extended或-fprecision选项,则舍入精度模式会保留extended精度.
single精度舍入模式会将结果舍入到24个有效位,而double精度舍入模式会将结果舍入到53个有效位.
在默认的extended精度模式下,结果被舍入到64个有效位.
该模式只控制在寄存器中结果的舍入精度,而不影响范围.
寄存器中所有的结果都使用了各种已扩展的双精度格式来舍入.
不过,存储在内存中的结果既舍入到目标格式的范围也舍入到目标格式的精度.
float类型的名义精度为single.
longdouble类型的名义精度为extended.
表A-12-fprecision值p的值含义单精度舍入到IEEE单精度值.
双精度舍入到IEEE双精度值.
extended舍入到最大可用精度.
附录AC++编译器选项A-27默认未指定-fprecision选项时,默认的舍入精度模式为extended.
警告此选项仅对x86设备且仅在编译主程序时使用才有效.
在SPARC设备上,该选项被忽略.
A.
2.
25-fround=r启动时设置有效的IEEE舍入模式.
该选项将IEEE754舍入模式设置为:编译器可以将其用于计算常量表达式程序初始化期间在运行时建立该含义与ieee_flags子例程的含义相同,可用于更改运行时的模式.
值r必须是下列值之一:默认未指定-fround选项时,默认的舍入模式为-fround=nearest.
警告如果先使用-fround=r编译一个例程,就还要使用相同的-fround=r选项来编译程序的所有例程;否则就会获得意外的结果.
表A-13-fround值r的值含义nearest舍入到最接近的数字并转变为偶数.
tozero舍入到零.
negative舍入到负无穷大.
positive舍入到正无穷大.
A-28《C++用户指南》2005年1月只有编译主程序时该选项才有效.
A.
2.
26-fsimple[=n]选择浮点优化首选项.
该选项允许优化器简化关于浮点运算的假定.
值如果存在n,则必须是0、1或2.
默认如果未指定-fsimple,则编译器使用-fsimple=0.
如果指定了-fsimple但未给定n任何值,则编译器使用-fsimple=1.
交互-fast暗示了-fsimple=2.
表A-14-fsimple值n的值含义0不允许简化假定.
保持严格的IEEE754一致性.
1允许保守简化.
产生的代码与IEEE754不完全一致,但多数程序所产生的数值结果没有更改.
使用-fsimple=1时,优化器可能要进行以下假定:进程初始化之后,不更改IEEE754的默认舍入/自陷模式.
除产生潜在浮点异常的计算不能删除外,产生不可视结果的计算都可以删除.
使用无穷大或NaNs作为操作数的计算需要将NaNs传送到它们的结果中,即x*0可以用零替换.
计算不依赖于零的符号.
使用-fsimple=1时,如果与误差或异常无关,则不允许优化器完全优化.
具体来讲,运行时将舍入模式保存为常量时,不能用产生不同结果的计算来替换浮点计算.
2允许主动的浮点优化.
由于在舍入过程中进行了更改,所以该优化会使许多程序产生不同的数值结果.
例如,允许优化器在指定循环中使用x*z来替换x/y的所有计算,其中要确保x/y在循环z=1/y中至少运算一次,并且在循环的执行期间y和z的值为常量值.
附录AC++编译器选项A-29警告该选项可以破坏IEEE754的一致性.
另请参见-fast《TechniquesforOptimizingApplications:HighPerformanceComputing》,由RajatGarg和IlyaSharapov撰写,详细解释了优化对精度的影响.
A.
2.
27-fstorex86:在以下值为真时,该选项使编译器将浮点表达式或函数的值转换为赋值左侧的类型,而不是将该值保留在寄存器中:将表达式或函数分配到变量.
表达式被转换为较短的浮点类型.
要关闭该选项,请使用-nofstore选项.
警告由于误差和截断,结果可能会与寄存器值所生成的结果不同.
另请参见-nofstoreA.
2.
28-ftrap=t[,t.
.
.
]设置IEEE捕获模式启动时有效,但不安装SIGFPE处理程序.
您可以使用ieee_handler(3M)或fex_set_handling(3M)启用自陷,并同时安装SIGFPE处理程序.
如果指定多个值,则按从左到右顺序处理列表.
A-30《C++用户指南》2005年1月值t可以是下列值之一:注意,选项的[no%]形式只用于修改%all和common值的含义,且必须用于其中的一个值,如以下示例所示.
选项自身的[no%]形式不会显式导致禁用特定的自陷.
默认如果您不指定-ftrap,则编译器假定-ftrap=%none.
示例-ftrap=%all,no%inexact意味着设置所有陷阱,但inexact除外.
警告如果先使用-ftrap=t编译一个例程,就还要使用相同的-ftrap=t选项来编译程序的所有例程;否则就会获得意外的结果.
使用-ftrap=inexact自陷时要小心操作.
只要浮点值不能精确表示,就会使用-ftrap=inexact产生自陷.
例如,以下语句就会产生这种情况:只有编译主程序时该选项才有效.
请小心使用该选项.
如果您希望启用IEEE自陷,请使用-ftrap=common.
表A-15-ftrap值t的值含义[no%]division[不]在除以零时自陷.
[no%]inexact[不]在结果不精确时自陷.
[no%]invalid[不]在无效操作上自陷.
[no%]overflow[不]在溢出上自陷.
[no%]underflow[不]在下溢上自陷.
%all在所有以上内容中自陷.
%none不在以上任何内容中自陷.
common在无效、除以零和溢出时自陷.
x=1.
0/3.
0;附录AC++编译器选项A-31另请参见ieee_handler(3M)、fex_set_handling(3M)手册页.
A.
2.
29-G生成动态共享库而不是可执行文件.
默认情况下,在命令行指定的所有源文件使用-xcode=pic13来编译.
生成使用模板的共享库时,多数情况下有必要将这些模板函数包括在共享库中,而这些函数已在模板数据库中实例化.
使用该选项可以将这些模板自动增加到所需的共享库中.
如果通过指定-G以及其他必须在编译时和链接时指定的编译器选项来创建共享对象,请确保在与生成的共享对象编译和链接时也指定这些相同的选项.
创建共享对象时,使用-xarch=v9编译的所有对象文件还必须使用第A-82页的第A.
2.
114节"-xcode=a"中建议的某个显式-xcode值进行编译.
交互如果未指定-c(仅编译选项),以下选项就会被传递到链接程序.
-dy-G-R警告不要使用ld-G来生成共享库,而要使用CC-G.
CC驱动程序自动将多个选项传递到C++所需的ld中.
使用-G选项时,编译器不将任何默认l选项传递到-ld选项.
如果您要使共享库具有对另一共享库的依赖性,就必须在命令行上传递必需的-l选项.
例如,如果您要使共享库具有对libCrun的依赖性,就必须在命令行上传递-lCrun.
另请参见-dy、-Kpic、-xcode=pic13、-ztext、ld(1)手册页第16-2页的第16.
3节"生成动态(共享)库".
A-32《C++用户指南》2005年1月A.
2.
30-g生成使用dbx(1)或调试程序进行调试或者使用性能分析器analyzer(1)进行分析所需的附加符号表信息.
指示编译器和链接程序准备进行调试和性能分析的文件或程序.
其任务包括:在对象文件和可执行文件的符号表中生成stabs详细信息.
生成某些"helper函数",调试程序可以调用这些函数来实现自身某些特性.
禁用函数的内联生成.
禁用优化的某些级别.
交互如果与-xOlevel(或与-O等效的选项)一起使用该选项,那么将会获得有限的调试信息.
有关更多信息,请参见第A-110页的第A.
2.
145节"-xOlevel".
如果您所用选项的优化级别为-xO4或更高,编译器就会提供全部优化的最多的符号信息.
指定该选项时,+d选项被自动指定.
注–在以前的发行版中,此选项强制编译器在默认情况下使用递增链接程序(ild),而不使用用于编译器的仅链接调用的链接程序(ld).
也就是说,使用-g时,只要您使用编译器来链接对象文件,编译器的默认行为就是自动调用ild而不是ld,除非您在命令行上指定了-G或源文件.
情况不再是这样,增量式链接程序不再可用.
要使用性能分析器的所有功能,请使用-g选项进行编译.
某些性能分析特性不需要-g时,您必须使用-g进行编译,以查看已注释的源码、某些函数级别信息和编译器注释消息.
有关详细信息,请参见analyzer(1)手册页和《程序性能分析工具》中的"编译您的程序以进行数据收集和分析".
使用-g生成的注释消息描述了编译器在编译程序时进行的优化和转换.
使用er_src(1)命令来显示与源代码交叉的消息.
警告如果单独进行编译和链接程序,那么将-g选项包括在一步骤中并将该选项从其他步骤中排除不会影响程序的正确性,但这样会影响调试程序的能力.
没有使用-g(或-g0)编译但使用-g(或-g0)链接的任何模块将不能正常调试.
注意,通常必须使用-g选项(或-g0选项)来编译包含函数main的模块才可用于调试.
附录AC++编译器选项A-33另请参见+d、-g0、-xs、analyzer(1)手册页,er_src(1)手册页,ld(1)手册页,使用dbx(关于stab的详细信息)调试程序,《程序性能分析工具》.
A.
2.
31-g0为调试编译并链接,但不禁用内联.
此选项与-g相同,但+d被禁用且dbx无法步入内联函数.
如果指定-g,并且优化级别为-xO3或更低,则编译器提供最佳效果符号信息.
尾部调用优化和后端内联被禁用.
另请参见+d、-g、《使用dbx调试程序》A.
2.
32-H打印包含文件的路径名称.
在标准错误输出(stderr)中,该选项打印当前编译中包含的每个#include文件的路径名称(每行一个名称).
A.
2.
33-h[]name将名称name分配到生成的动态共享库.
这是一个加载器选项,传递到ld.
通常,-h后的名称应该与-o后的名称完全相同.
在-h和name之间的空格是可选的.
编译时的加载器将指定名称分配到正在创建的共享动态库中,并将该名称作为库的内部名称记录在库文件中.
如果没有-hname选项,在库文件中就没有记录内部名称.
每个可执行文件都具有所需的共享库文件列表.
当运行时链接程序将库链接到可执行文件中时,链接程序将内部名称从库复制到所需共享库文件的列表中.
如果没有共享文件的内部名称,链接程序就复制共享库文件的路径.
A-34《C++用户指南》2005年1月示例A.
2.
34-help与-xhelp=flags相同.
A.
2.
35-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目录中注–如果拼写与标准头文件的名称相匹配,也可参见第12-13页的第12.
7.
5节"标准头文件实现".
交互-I-选项使您能够覆盖默认的搜索规则.
如果指定了-library=no%Cstd,那么编译器在其搜索路径中就不包括编译器提供的与C++标准库相关的头文件.
请参见第12-11页的第12.
7节"替换C++标准库".
example%CC-G-olibx.
so.
1-hlibx.
so.
1a.
ob.
oc.
o附录AC++编译器选项A-35如果未使用-ptipath,编译器就会在-Ipathname中查找模板文件.
请使用-Ipathname而不要使用-ptipath.
该选项会累积而不覆盖.
警告勿将编译器安装区域/usr/include、/lib或/usr/lib指定为搜索目录.
另请参见-I-A.
2.
36-I-将包含文件的搜索规则更改为:对于#include"foo.
h"形式的包含文件,按以下顺序搜索目录:1.
使用-I选项(包括在-I-前后)命名的目录2.
编译器提供的C++头文件、ANSIC头文件和专用文件的目录中3.
/usr/include目录对于#include形式的包含文件,按以下顺序搜索目录.
1.
使用出现在-I-之后的-I选项命名的目录2.
编译器提供的C++头文件、ANSIC头文件和专用文件的目录中3.
/usr/include目录注–如果包含文件的名称与标准头文件的名称相匹配,也可参见第12-13页的第12.
7.
5节"标准头文件实现".
A-36《C++用户指南》2005年1月示例以下示例显示了编译prog.
cc时使用-I-的结果.
以下命令显示了为#include"foo.
h"形式的包含语句搜索当前目录(包含文件的目录)的默认行为.
在inc/a.
h中处理#include"c.
h"语句时,编译器包括来自inc子目录的c.
h头文件.
在prog.
cc中处理#include"c.
h"语句时,编译器包括了源于包含prog.
cc目录的c.
h文件.
注意,-H选项指示编译器打印包含文件的路径.
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;#endifexample%CC-c-Iinc-Hprog.
ccinc/a.
hinc/c.
hinc/b.
hinc/c.
hc.
h附录AC++编译器选项A-37下一条命令显示了-I-选项的结果.
编译器处理#include"foo.
h"形式的语句时,并不首先在包含的目录中查找.
相反,编译器按照目录在命令行上出现的顺序,搜索通过-I选项命名的目录.
在inc/a.
h中处理#include"c.
h"语句时,编译器包括了.
/c.
h头文件,而没有包括inc/c.
h头文件.
交互-I-出现在命令行时,编译器不再搜索当前目录,除非该目录显式列于-I指令中.
该结果甚至还适用于#include"foo.
h"形式的包括语句.
警告只有命令行上的第一个-I-会引起描述的行为.
勿将编译器安装区域/usr/include、/lib或/usr/lib指定为搜索目录.
A.
2.
37-i告知链接程序ld(1)忽略任何LD_LIBRARY_PATH设置.
A.
2.
38-inline与-xinline相同.
A.
2.
39-instances=a控制模板实例的放置和链接.
example%CC-c-I.
-I--Iinc-Hprog.
ccinc/a.
h.
/c.
hinc/b.
hinc/c.
h.
/c.
hA-38《C++用户指南》2005年1月值a必须是下列值之一:默认如果未指定-instances,则假定-instances=global.
另请参见第7-2页的第7.
2.
4节"模板实例的放置和链接".
A.
2.
40-instlib=filename使用该选项以避免在库(共享或静态)和当前对象中生成重复的模板实例.
一般来说,如果程序与函数库共享大量的实例,则可以试试-instlib=filename选项,看看编译时间是否会减少.
表A-16-instances值a的值含义extern将全部所需示例放置到comdat部分的模块系统信息库并赋予全局链接.
(如果系统信息库中的实例过期,就会被重新实例化.
)请注意:如果以不同的步骤编译和链接并为编译步骤指定了-instance=extern,则也必须为链接步骤指定-instance=extern.
显式将显式实例化的实例放置到当前对象文件中并赋予全局链接.
不生成其他任何所需实例.
全局将全部所需的实例放置到当前对象文件中并赋予全局链接.
semiexplicit将显式实例化的实例放置到当前对象文件中并赋予全局链接.
将显式实例所需的全部实例放置到当前对象文件中并赋予全局链接.
不生成其他任何所需实例.
static请注意:-instances=static已过时.
没有任何理由再使用-instances=static,因为-instances=global现在向您提供了所有静态的优点而没有它的缺点.
以前编译器中提供的该选项用于克服此编译器版本中不存在的问题.
将全部所需的实例放置到当前对象文件中并赋予静态链接.
附录AC++编译器选项A-39值:使用filename参数以指定包含现有模块实例的库(已知的).
filename参数必须包含正斜杠"/"字符.
与当前目录相关的路径要使用点斜杠".
/".
默认:-instlib=filename选项不是默认选项,只有在指定该选项之后才能使用.
该选项可被多次指定和累积.
示例:假定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.
41-KPICSPARC:与-xcode=pic32相同.
x86:与-Kpic相同.
生成共享库时使用该选项编译源文件.
对全局数据的每个引用都生成为全局偏移表中指针的非关联化.
每个函数调用都通过过程链接表在pc相对地址模式中生成.
A-40《C++用户指南》2005年1月A.
2.
42-KPICSPARC:与-xcode=pic13相同.
x86:使用与位置无关的代码进行编译.
生成共享库时使用该选项编译源文件.
对全局数据的每个引用都生成为全局偏移表中指针的非关联化.
每个函数调用都通过过程链接表在pc相对地址模式中生成.
A.
2.
43-keeptmp保留编译时创建的临时文件.
加上-verbose=diags,该选项就可用于调试.
另请参见-v、-verboseA.
2.
44-Lpath将path增加到目录列表以搜索库.
该选项被传递到ld.
path命名的目录先于编译器提供的目录搜索.
交互该选项会累积而不覆盖.
警告勿将编译器安装区域/usr/include、/lib或/usr/lib指定为搜索目录.
A.
2.
45-llib将libraryliblib.
a或liblib.
so增加到链接程序的库搜索列表.
附录AC++编译器选项A-41该选项被传递到ld.
正常的库具有诸如liblib.
a或liblib.
so的名称,其中lib和.
a或.
so部分是必需的.
应该使用该选项指定lib部分.
将尽可能多的库输入到在单一命令行上,这些库按照-Ldir指定的顺序搜索.
请在对象文件名之后使用该选项.
交互该选项会累积而不覆盖.
在源码和对象的列表之后放入-lx可以确保按照正确顺序搜索这些库.
警告要确保正确的库链接顺序,必须使用-mt而不是-lthread与libthread链接.
另请参见-Ldir、-mt、第12章和《Tools.
h++ClassLibraryReference》A.
2.
46-libmieee与-xlibmieee相同.
A.
2.
47-libmil与-xlibmil相同.
A.
2.
48-library=l[,l.
.
.
]将指定的CC提供的库放入编译和链接中.
A-42《C++用户指南》2005年1月值对于兼容模式(-compat[=4]),l必须是下列值之一.
在标准模式(默认模式)下,l必须是下列值之一:表A-17用于兼容模式的-library值l的值含义[no%]f77已过时.
应该使用-xlang=f77.
[no%]f90已过时.
应该使用-xlang=f90.
[no%]f95已过时.
应该使用-xlang=f95.
[no%]rwtools7[不]使用传统iostreamTools.
h++版本7.
[no%]rwtools7_dbg[不]使用可调试的Tools.
h++版本7.
[no%]complex[不]使用复数运算的libcomplex.
[no%]interval已过时.
不要使用.
使用-xia.
[no%]libC[不]使用libCC++支持库.
[no%]gc[不]使用libgc垃圾收集.
[no%]sunperf[不]使用SunPerformanceLibrary%none仅使用libCC++库.
表A-18用于标准模式的-library值l的值含义[no%]f77已过时.
应该使用-xlang=f77.
[no%]f90已过时.
应该使用-xlang=f90.
[no%]f95已过时.
应该使用-xlang=f95.
[no%]rwtools7[不]使用传统iostreamTools.
h++版本7.
[no%]rwtools7_dbg[不]使用可调试的Tools.
h++版本7.
[no%]rwtools7_std[不]使用标准iostreamTools.
h++版本7.
[no%]rwtools7_std_dbg[不]使用可调试的标准iostreamTools.
h++7.
[no%]interval已过时.
不要使用.
使用-xia.
[no%]iostream[不]使用libiostream传统iostream库.
[no%]Cstd[不]使用libCstdC++标准库.
[不]包括编译器提供的C++标准库头文件.
[no%]Crun[不]使用libCrunC++运行库.
[no%]gc[不]使用libgc垃圾收集.
附录AC++编译器选项A-43默认兼容模式(-compat[=4])如果未指定-library,则假定为-library=libC.
除非libC库使用-library=no%libC被特别排除,否则始终包括该库.
标准模式(默认模式)除非libCstd库使用-library=%none、-library=no%Cstd或-library=stlport4被特别排除,否则始终包括该库.
始终包括libCrun库.
无论是标准模式还是兼容模式,始终包括libm和libc库,即使指定了-library=%none.
示例要在没有任何C++库(除libCrun)的标准模式下进行链接,请使用:要在标准模式下包括传统iostreamRogueWavetools.
h++库,请使用:要在标准模式下包括标准iostreamRogueWavetools.
h++库,请使用:[no%]stlport4[不]使用STLport的标准库实现版本4.
5.
3代替默认的libCstd.
关于使用STLport实现的更多信息,请参见第13-13页的第13.
3节"STLport".
[no%]stlport4_dbg[不]使用STLport可调试的库.
[no%]sunperf[不]使用SunPerformanceLibrary%none仅使用libCrunC++库.
example%CC-library=%noneexample%CC-library=rwtools7,iostreamexample%CC-library=rwtools7_std表A-18用于标准模式的-library值(续)l的值含义A-44《C++用户指南》2005年1月要在兼容模式下包括传统iostreamRogueWavetools.
h++库,请使用:交互使用-library指定库时,正确的-I路径在编译期间设置.
正确的-L,-YP,-R路径和-l选项在链接期间设置.
该选项会累积而不覆盖.
在使用区间运算库时,必须包括以下库之一:libC、libCstd或libiostream.
-library选项的使用可以确保指定库的-l选项按正确顺序发送.
例如,-l选项按照-library=rwtools7,iostream和-library=iostream,rwtools7的-lrwtool-liostream顺序传递到ld.
指定的库在系统支持库链接之前链接.
不能在相同命令行上使用-library=sunperf和-xlic_lib=sunperf.
不能在相同命令行上使用-library=stlport4和-library=Cstd.
每次只能使用一个RogueWave工具库,而且不能使用任何具有-library=stlport4的RogueWave工具库.
当在标准模式(默认模式)下包括传统iostreamsRogueWave工具库时,还必须包括libiostream(请参见《C++迁移指南》).
仅在标准模式下可以使用标准iostreamsRogueWave工具库.
以下命令示例显示了RogueWavetools.
h++库选项的有效和无效的使用.
如果既包括了libCstd也包括了libiostream,就必须注意不要在程序中使用iostreams的新的和旧的形式(如cout和std::cout)来访问同一文件.
如果从传统和标准iostreams代码访问同一文件,那么在相同的程序中混合标准iostreams和传统iostreams可能会出现问题.
既不链接libC也不链接libCrun的程序不能使用C++语言的所有特性.
example%CC-compat-library=rwtools7%CC-compat-library=rwtools7foo.
cc#includeintmain(){std::coutstructS{voidimf(){}staticvoidsmf(){}};templateclassS;intmain(){}example%附录AC++编译器选项A-61指定-template=geninlinefuncs时,即使在该程序中不调用S的两个成员函数,也会在对象文件中生成这两个函数.
另请参见第7-2页的第7.
2.
2节"整个类实例化"、第7-7页的第7.
5节"模板定义搜索"A.
2.
91-time与-xtime相同.
A.
2.
92-Uname删除预处理程序符号name的初始化定义.
该选项会删除宏符号name的所有初始化定义,该符号在命令行上通过-D创建,包括了CC驱动程序隐式放置的内容.
该选项对任何其他预定义的宏和源文件中的宏定义都没有影响.
要查看CC驱动程序置于命令行上的-D选项,请将-dryrun选项增加到命令行.
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_]A-62《C++用户指南》2005年1月示例以下命令取消了预定义符号__sun的定义.
foo.
cc中的预处理程序语句(例如#ifdef(__sun))会判断出该符号是未定义的.
交互您可以在命令行上指定多个-U选项.
所有的-U选项都在任何-D选项出现之后处理.
也就是说,如果在命令行上为-D和-U指定了相同的name,则name是未定义的,这与选项出现的顺序无关.
另请参见-DA.
2.
93-unroll=n与-xunroll=n相同.
A.
2.
94-V与-verbose=version相同.
A.
2.
95-v与-verbose=diags相同.
A.
2.
96-vdelx已过时,不使用.
仅兼容模式(-compat[=4]):example%CC-U__sunfoo.
cc附录AC++编译器选项A-63对于使用delete[]的表达式,该选项生成对运行时库函数_vector_deletex_的调用,而不生成对_vector_delete_的调用.
函数_vector_delete_使用两个参数:要删除的指针以及每个数组元素的大小.
函数_vector_deletex_的行为与_vector_delete_的行为相同,但前者使用第三个参数:类的析构函数的地址.
第三个参数不用于该函数,而是供第三方供应商使用.
默认该编译器为使用delete[]的表达式生成对_vector_delete_的调用.
警告这是在以后的发行版本中要删除的废弃选项.
除非您已从第三方供应商购买了某些软件且供应商推荐使用该选项,否则请不要使用该选项.
A.
2.
97-verbose=v[,v_]控制编译器详细内容.
值v必须是下列值之一:默认如果未指定-verbose,则假定为-verbose=%none.
表A-23-verbose值v的值含义[no%]diags[不]为每个编译传递打印命令行.
[no%]template[不]打开模板实例化verbose模式(有时称为"检验"模式).
verbose模式显示编译过程中实例化的每个阶段.
[no%]version[不]指定CC驱动程序打印调用程序的名称和版本编号.
%all调用以上所有内容.
%none-verbose=%none与-verbose=no%template,no%diags,no%version相同.
A-64《C++用户指南》2005年1月交互该选项会累积而不覆盖.
A.
2.
98+w标识可能产生不可预料结果的代码.
如果函数过大而无法内联或声明的程序元素未被使用,那么+w选项不再生成警告.
该警告不指定源码中的真正问题,因此不适合某些开发环境.
将这些警告从+w删除就可以在这些环境下更主动的使用+w.
这些警告仍然可以与+w2选项一起使用.
该选项生成如下关于有问题构造的其他警告:不可移植可能出错低效默认如果未指定+w,则编译器警告构造极可能出现问题.
交互某些C++标准头文件在使用+w编译时会产生警告.
另请参见-w、+w2A.
2.
99+w2发出由+w提供的所有警告,以及关于技术违规的附加警告.
这类技术违规可能是无害的,但可能会降低系统的最大可移植性.
+w2选项不再发出关于依赖于实现系统头文件中构造的警告.
因为系统头文件是实现,所以发出警告是不合适的.
从+w2删除这些警告可以更主动地使用该选项.
警告某些Solaris操作系统和C++标准头文件在使用+w2编译时会产生警告.
附录AC++编译器选项A-65另请参见+wA.
2.
100-w禁止大多数警告消息.
该选项使编译器不打印警告消息.
不过某些警告(尤其是严重的记时错误)不能被禁止.
另请参见+wA.
2.
101-Xm与-features=iddollar相同.
A.
2.
102-xa为文件配置生成代码.
如果在编译时进行设置,则TCOVDIR环境变量会指定覆盖(.
d)文件所在的目录如果该变量未设置,则覆盖(.
d)文件仍与source文件保存在同一目录中.
使用该选项是为了向后兼容旧的覆盖文件.
交互-xprofile=tcov选项和-xa选项在单一可执行文件中兼容.
也就是说,您可以链接程序,其中包含了用-xprofile=tcov编译过的某些文件和用-xa编译的其他文件.
您不能同时用这两个选项来编译单一文件.
-xa选项与-g不兼容.
警告如果单独进行编译和链接且使用-xa编译,就要确保也使用-xa进行链接,否则会产生意外的结果.
A-66《C++用户指南》2005年1月另请参见-xprofile=tcov、tcov(1)手册页、《程序性能分析工具》.
A.
2.
103-xalias_level[=n](SPARC)指定以下命令时,C++编译器可以执行基于类型的别名分析和优化:-xalias_level[=n]其中n是any、simple或compatible.
-xalias_level=any在此分析级别上,编译器假定任何类型都可以为其他类型起别名.
不过尽管只是假定,但还是可以执行某些优化.
-xalias_level=simple编译器假定简单的类型没有别名.
具体来说就是具有动态类型的存储对象,这些类型是以下简单类型之一:只能通过以下类型的左值访问:对象的动态类型对象动态类型的constant或volatile限定版本,与对象动态类型相对应的带符号或不带符号的类型与对象动态类型的constant或volatile限定版本相对应的带符号或不带符号的类型在其成员(包括递归的子集成员或包含的联合)中包括上述类型的聚集或联合类型char或unsignedchartype-xalias_level=compatible编译器假定布局不兼容类型没有别名.
存储对象只能通过以下类型的左值访问:对象的动态类型对象动态类型的constant或volatile限定版本,与对象动态类型相对应的带符号或不带符号的类型charshortintlongint浮点signedcharunsignedshortintunsignedlongint双精度unsignedcharintlonglongint长双精度wchar_tunsignedintunsignedlonglongint枚举类型数据指针类型函数指针类型数据成员指针类型函数成员指针类型附录AC++编译器选项A-67与对象动态类型的constant或volatile限定版本相对应的带符号或不带符号的类型在其成员(包括递归的子集成员或包含的联合)中包括上述类型的聚集或联合类型对象动态类型的基类类型(可能用constant或volatile限定)char或unsignedchartype.
编译器假定所有引用的类型都与相应存储对象的动态类型是布局兼容的.
两种类型在以下情况下是布局兼容的:如果两个类型相同,则这两个类型就是布局兼容的类型.
如果两个类型仅在constant或volatile限定中不同,则这两个函数是布局兼容的类型.
每个存在的有符号整数类型对应(但是不相同)一个无符号整数类型.
这些对应的类型是布局兼容的.
如果两个枚举类型具有相同的基础类型,则它们是布局兼容的.
如果两个PlainOldData(POD)结构类型具有相同数量的成员,并且对应的成员(按顺序)具有布局兼容的类型,那么这两个结构类型是布局兼容的.
如果两个POD联合类型具有相同数量的成员,并且对应的成员(按顺序)具有布局兼容的类型,那么这两个联合类型是布局兼容的.
在某些情况下具有存储对象动态类型的引用可能是非布局兼容的:如果POD联合包含了两个或两个以上共享通用初始序列的POD结构,且POD联合对象当前包含了其中一个POD结构,就可以检查任何POD结构的通用初始部分.
对包含一个或多个初始成员的序列来说,如果相应成员具有布局兼容类型(适用于位字段)和相同宽度,则两个POD结构共享一个通用初始序列.
指向POD结构对象的指针(使用reinterpret_cast适当转换)将指向该结构的初始成员,而如果该成员是位字段则指向该结构所在的单元.
默认如果未指定-xalias_level,则编译器将选项设置为-xalias_level=any.
如果指定了-xalias_level但未提供任何值,则编译器将选项设置为-xalias_level=compatible.
交互编译器在-xO2及低于它的优化级别下不执行基于类型的别名分析.
A-68《C++用户指南》2005年1月警告如果正使用reinterpret_cast或等效的旧式类型转换,那么程序就可能违反分析的假定.
此外,联合类型也违反了分析的假定,如以下示例所示.
A.
2.
104-xar创建归档库.
生成使用模板的C++归档文件时,多数情况下有必要将这些模板函数包括在该归档文件中.
这些函数已在模板数据库中被实例化.
使用该选项可以将这些模板自动增加到所需的归档文件中.
值指定-xar调用ar-c-r并重新创建归档文件.
示例以下命令行归档包含在库和对象文件中的模板函数.
警告不在命令行上从模板数据库增加.
o文件.
不直接使用ar命令生成归档文件.
使用CC-xar以确保模板实例化自动包括在归档文件中.
unionbitbucket{inti;floatf;};intbitsof(floatf){bitbucketvar;var.
f=3.
6;returnvar.
i;}example%CC-xar-olibmain.
aa.
ob.
oc.
o附录AC++编译器选项A-69另请参见ar(1)、第16章A.
2.
105-xarch=isa指定目标指令集架构(ISA).
该选项将编译器生成的代码限制到特定指令集架构的指令.
该选项不保证使用任何目标特定的指令.
不过,使用该选项会影响二进制程序的可移植性.
SPARC值表A-24给出了SPARC平台上每个-xarch关键字的详细信息.
表A-24SPARC平台的-xarch值isa的值含义generic在多数系统上生成高性能的32位对象二进制文件.
这是默认行为.
该选项在多数处理器上使用高性能的最佳指令集,同时不降低处理器的主要性能.
如果需要,在新的发行版本中会调整"最佳"指令集的定义.
目前,它等效于-xarch=v7.
generic64在多数64位平台架构上生成高性能的64位对象二进制文件.
该选项在具有64位内核的Solaris操作系统中使用高性能的最佳指令集,同时不降低操作环境的性能.
如果需要,在新的发行版本中会调整"最佳"指令集的定义.
目前,它等效于-xarch=v9.
native在本系统上生成高性能的32位对象二进制文件.
这是-fast选项的默认值.
编译器在处理器运行的系统上选择适当的设置.
native64在本系统上生成高性能的64位对象二进制文件.
编译器在处理器运行的系统上为生成系统的64位二进制选择适当的设置.
v7编译用于SPARC-V7ISA.
(已废弃)当前的Solaris操作系统不再支持SPARCV7体系结构,并且使用此选项编译的程序在当前平台上的运行速度较慢.
v8a编译用于SPARC-V8ISAV8a版本.
根据定义,V8a意味着V8ISA,但不包括fsmuld指令.
该选项在V8aISA上使编译器生成高性能代码.
示例:基于microSPARCI芯片架构的任何系统v8编译用于SPARC-V8ISA.
在V8架构上使编译器生成高性能代码.
示例:SPARCstation10A-70《C++用户指南》2005年1月v8plus编译用于SPARC-V9ISA的V8plus版本.
这是默认设置.
根据定义,V8plus意味着V9ISA,但只限于由V8plusISA规范所定义的32位子集,而不包括可视化指令集(VIS)和特定实现的ISA扩展.
该选项在V8plusISA上使编译器生成高性能代码.
产生的对象代码是SPARC-V8+ELF32格式且只在SolarisUltraSPARC环境下执行(不能在V7或V8处理器上运行).
示例:基于UltraSPARC芯片架构的任何系统v8plusa编译用于SPARC-V9ISA的V8plusa版本.
根据定义,V8plusa意味着V8plus架构加可视化指令集(VIS)版本1.
0和UltraSPARC扩展.
该选项使编译器在UltraSPARC架构上生成高性能代码,但只限于V8plus规范定义的32位子集.
产生的对象代码是SPARC-V8+ELF32格式且只在SolarisUltraSPARC环境下执行(不能在V7或V8处理器上运行).
示例:基于UltraSPARC芯片架构的任何系统v8plusb编译用于具有UltraSPARCIII扩展的SPARC-V8plusISAV8plusb版本.
使编译器为UltraSPARC架构生成对象代码,加上具有UltraSPARCIII扩展的可视化指令集(VIS)版本2.
0.
产生的对象代码是SPARC-V8+ELF32格式且只在SolarisUltraSPARCIII环境下执行.
用该选项进行编译时要在UltraSPARCIII架构上使用高性能的最佳指令集.
表A-24SPARC平台的-xarch值(续)isa的值含义附录AC++编译器选项A-71另请注意:SPARC指令集体系结构V8和V8a均是二进制兼容的.
由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)浮点指令,但编译器不在它生成的代码中使用这些指令.
v9编译用于SPARC-V9ISA.
在V9SPARC架构上使编译器生成高性能代码.
产生的.
o对象文件是ELF64格式且只能与相同格式的其他SPARC-V9对象文件链接.
产生的可执行文件只能在UltraSPARC处理器上运行,该处理器运行具有64位内核的64位Solaris操作系统.
在启用64位的Solaris系统下编译时,只有-xarch=v9可用.
v9a编译用于具有UltraSPARC扩展的SPARC-V9ISA.
将可视化指令集(VIS)和UltraSPARC处理器的特定扩展增加到SPARC-V9ISA,并使编译器在V9SPARC架构上生成高性能代码.
产生的.
o对象文件是ELF64格式且只能与相同格式的其他SPARC-V9对象文件链接.
产生的可执行文件只能在UltraSPARC处理器上运行,该处理器运行具有64位内核的64位Solaris操作系统.
在启用64位的Solaris操作系统下编译时,只有-xarch=v9a可用.
v9b编译用于具有UltraSPARCIII扩展的SPARC-V9ISA.
将UltraSPARCIII扩展和VIS版本2.
0增加到SPARC-V9ISA的V9a版本.
用该选项进行编译时要在SolarisUltraSPARCIII环境下使用高性能的最佳指令集.
产生的对象代码是SPARC-V9ELF64格式且只能与相同格式的其他SPARC-V9对象文件链接.
产生的可执行文件只能在UltraSPARCIII处理器上运行,该处理器运行具有64位内核的启用64位的Solaris操作系统.
在启用64位的Solaris操作系统下编译时,只有-xarch=v9a可用.
表A-24SPARC平台的-xarch值(续)isa的值含义A-72《C++用户指南》2005年1月x86值:表A-25给出了x86平台上每个-xarch标志的详细信息.
警告为了在兼容Solarisx86SSE或SSE2平台上运行而将-xarch设置为sse(Pentium3)或sse2(Pentium4)以进行编译的程序只能在支持SSE或SSE2的平台上运行.
将-xarch设置为pentium_proa以进行编译的程序必须在支持AMD3DNow!
和3DNow!
扩展的平台上运行.
通过将-xarch设置为ssea或sse2a而编译的程序必须在支持AMD3DNow!
、3DNow!
扩展的平台以及支持SSE或SSE2的平台上运行.
表A-25x86平台的-xarch值isa的值含义386在该发行版本中generic和386是等效的.
amd64为64位Solarisx86平台进行编译.
amd64a将AMD扩展(3DNow!
、3DNow!
扩展和MMX扩展)添加到AMD64体系结构中,并生成64位ELF格式二进制文件.
generic编译以便在多数系统上达到较高的性能.
这是默认设置.
该选项在多数处理器上使用高性能的最佳指令集,同时不降低处理器的主要性能.
如果需要,在新的发行版本中会调整"最佳"指令集的定义.
generic64在多数64位平台体系结构上生成高性能的64位对象二进制文件.
该选项在具有64位内核的Solaris操作系统中使用高性能的最佳指令集,同时不降低操作环境的性能.
如果需要,在新的发行版本中会调整"最佳"指令集的定义.
native为了在此系统上获得良好性能而进行编译.
这是-fast选项的默认值.
编译器为当前正编译的系统处理器选择适当的设置.
pentium_pro将指令集限制到pentium_pro体系结构.
pentium_proa将AMD扩展(3DNow!
、3DNow!
扩展和MMX扩展)添加到32位pentium_pro体系结构中.
sse将SSE指令集添加到pentium_pro体系结构.
ssea将AMD扩展(3DNow!
、3DNow!
扩展和MMX扩展)添加到32位pentium_pro体系结构中.
sse2将SSE2指令集添加到pentium_pro体系结构.
sse2a将AMD扩展(3DNow!
、3DNow!
扩展和MMX扩展)添加到32位pentium_pro体系结构中.
附录AC++编译器选项A-73从Solaris94/04开始的操作系统发行版本在兼容Pentium3或4的平台上支持SSE/SSE2.
早期版本的Solaris操作系统不支持SSE/SSE2.
类似地,使用-xarch=amd64为Solarisx86AMD64平台编译的程序必须在支持AMD64位体系结构的平台上运行.
请注意,AMD64体系结构支持SSE/SSE2.
使用-xarch=amd64a编译的程序必须在支持AMD64位体系结构以及AMD3DNOW!
和AMD3DNow!
扩展的平台上运行.
操作系统将对使用这些专用-xarch硬件标志编译和生成的程序二进制文件进行检查,看其是否在适当启用的硬件上运行.
这种验证适用于在Solaris10操作系统上运行的SunStudio11.
在Solaris10以前的系统上,不执行任何验证,而是由用户来负责确保将使用这些标志生成的对象部署在相应的硬件上.
如果在不支持相应的功能或指令集扩展的平台上运行使用这些-xarch标志编译的程序,则会在不出现任何显式警告消息的情况下发生"非法指令"错误、段故障或错误结果.
这一警告还会扩展到采用.
il内联汇编语言函数或__asm汇编程序代码(采用SSE、SSE2、AMD64和AMD3DNow!
指令以及AMD3DNow!
扩展)的程序.
如果在单独的步骤中编译和链接,请始终使用编译器和相同的-xarch设置进行链接,以确保链接正确的启动例程.
x86上的运算结果可能与SPARC上的结果不同,这是由于x8680字节浮点寄存器造成的.
要最大限度地减少这些差异,请使用-fstore选项,或者使用-xarch=sse2进行编译(如果硬件支持SSE2).
SPARC默认设置目前,C++编译器生成其代码的默认体系结构是v8plus(UltraSPARC).
以后的发行版将取消对v7的支持.
新的默认设置可以使几乎所有当前使用的计算机的运行时性能更佳.
但是,在默认情况下,设计用于在UltraSPARC之前的计算机上进行部署的应用程序将不再在那些计算机上执行.
使用-xarch=v8编译可以确保这些应用程序在那些计算机上执行.
如果要在v8系统上部署,则必须在每个编译器命令行以及任何链接时命令上显式指定选项-xarch=v8.
提供的系统库将可以在v8体系结构上运行.
如果要在v7系统上部署,则必须在每个编译器命令行以及任何链接时命令上显式指定选项-xarch=v7.
提供的系统库将使用v8指令集.
对于此发行版来说,唯一支持v7的操作系统是Solaris8OS发行版.
遇到v8指令时,Solaris8操作系统会在软件中解释指令.
程序会运行,但性能将下降.
A-74《C++用户指南》2005年1月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.
-compat[=4]不能与-xarch=generic64、-xarch=native64、-xarch=v9、-xarch=v9a或-xarch=v9b同时使用.
警告如果带优化使用该选项,那么在指定架构上适当选择就可以提供高性能的可执行文件.
但如果选择不当就会导致性能的严重降级,或导致在预定目标平台上无法执行二进制程序.
如果单独进行编译和链接,请确保在两个步骤中为-xarch指定了相同的值.
A.
2.
106-xautopar注–该选项不接受OpenMP并行化指令,Sun特定的MPpragma已过时并且不再受支持.
有关该标准指令的迁移信息,请参见《OpenMPAPI用户指南》.
(SPARC)为多个处理器打开自动并行化.
进行依赖性分析(分析循环以了解迭代间数据依赖性)和循环重构.
如果优化级别不是-xO3或更高级别,则将优化级别提高到-xO3并发出警告.
如果要执行自己的线程管理,请不要使用-xautopar.
要使执行速度更快,则该选项需要多处理器系统.
在单处理器系统上,最终的二进制程序通常运行较慢.
example%CC-xtarget=ultra2-xarch=v8plusbfoo.
cc附录AC++编译器选项A-75要确定您使用的处理器数量,请使用psrinfo命令:要请求多个处理器,请设置PARALLEL环境变量.
默认值为1.
请求的处理器数量不能超出可用的处理器数量.
PARALLEL环境变量的值不能大于单用户计算机上的处理器的数量.
在多用户计算机上,PARALLEL环境变量值应该小于处理器数量,以避免计算机过载.
如果您使用-xautopar并在一个步骤中进行编译和链接,则链接将自动包括微任务库和线程安全C运行时库.
如果您使用-xautopar并分别在单独的步骤中进行编译和链接,则您还必须链接-xautopar.
另请参见第A-113页的第A.
2.
146节"-xopenmp[=i]"A.
2.
107-xbinopt={prepare|off}(SPARC)指示编译器准备二进制文件以随后进行优化、转换和分析,请参见binopt(1).
该选项可用于生成可执行文件或共享对象.
如果在单独的步骤中进行编译,则-xlinkopt必须同时出现在编译和链接步骤中:如果某些源代码不能用于编译,则仍然可以使用该选项来编译代码的其余部分.
在后面的创建最终二进制文件的链接步骤中必须使用该选项.
在此类情况下,只有通过该选项编译的代码才能进行优化、转换或分析.
默认默认值为-xbinopt=off.
%psrinfo0on-linesince01/12/9510:41:541on-linesince01/12/9510:41:543on-linesince01/12/9510:41:544on-linesince01/12/9510:41:54example%cc-c-xO1-xbinopt=preparea.
cb.
cexample%cc-omyprog-xbinopt=preparea.
oA-76《C++用户指南》2005年1月交互该选项必须用于-xO1或更高的优化级别才有效.
在使用此选项进行生成时,二进制文件大小略有增加.
使用-xbinopt=prepare和-g编译会将调试信息包括在内,从而增加了可执行文件的大小.
A.
2.
108-xbuiltin[={%all|%none}]启用或禁用标准库调用的最佳优化.
默认情况下,编译器会将标准库头文件中声明的函数视为普通函数.
不过,编译器会将某些函数识别为"内部"或"内建".
视为内建函数时,编译器可以生成更有效的代码.
例如,编译器可以识别无副作用的函数,且通常为给定的相同输入返回相同的输出.
编译器可将部分函数直接生成为内联函数.
有关如何阅读对象文件中的编译器注释以确定编译器实际为哪些函数进行替换的说明,请参见er_src(1)手册页.
-xbuiltin=%all选项会请求编译器识别尽可能多的内建标准函数.
所识别函数的确切列表在不同的编译器代码生成器版本中各不相同.
-xbuiltin=%none选项会生成默认编译器行为,编译器对内建函数不执行任何优化.
默认如果未指定-xbuiltin选项,则编译器假定-xbuiltin=%none.
如果仅指定了-xbuiltin,则编译器假定-xbuiltin=%all.
交互宏-fast的扩展包括了-xbuiltin=%all.
示例下面的编译器命令请求标准库调用的特殊处理.
example%CC-xbuiltin-cfoo.
cc附录AC++编译器选项A-77下面的编译器命令请求不对标准库调用进行特别处理.
注意,宏-fast的扩展包括了-xbuiltin=%all.
A.
2.
109-xcache=cSPARC:定义优化器使用的缓存属性.
该选项指定了优化器可以使用的缓存属性,不保证使用每个特定的缓存属性.
注–该选项可单独使用,但它是-xtarget选项的部分扩展,主要用途是覆盖-xtarget选项提供的值.
此发行版本引入了一个可选属性[/ti],它设置了可以共享缓存的线程数.
值c必须是下列值之一:缓存属性的定义si/li/ai/ti如下:example%CC-fast-xbuiltin=%none-cfoo.
cc表A-26-xcache的值c的值含义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缓存属性属性定义sii级别的数据缓存大小以千字节为单位lii级别的数据缓存行大小以字节为单位aii级别的数据缓存关联A-78《C++用户指南》2005年1月例如,i=1指定了级别1缓存属性s1/l1/a1.
默认如果未指定-xcache,则默认假定为-xcache=generic.
该值指示了编译器在多数SPARC处理器上使用缓存属性来获得高性能,而不降低任何处理器的性能.
如果没有指定t值,则默认值为1.
示例-xcache=16/32/4:1024/32/1指定了:另请参见-xtarget=tA.
2.
110-xcg[89|92]已废弃,不要使用此选项.
当前的Solaris操作系统软件不再支持SPARCV7体系结构.
使用此选项编译生成的代码在当前的SPARC平台中运行较慢.
请改用-O,并使用-xarch、-xchip和-xcache的编译器默认设置.
A.
2.
111-xchar[=o]有些系统将字符定义成无符号类型,该选项使得迁移这些系统上的代码变得容易.
如果不是从这样的系统中迁移,最好不要使用该选项.
只有那些依赖字符类型符号的程序才需要重写,它们要改写成显式指定有符号或者无符号.
级别1缓存具有级别2缓存具有16千字节1024千字节32字节行大小32字节行大小4方向关联指示映射关联附录AC++编译器选项A-79值您可以用下列值之一来替换o:默认如果未指定-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-27-xchar值值含义signed将声明为字符的字符常量和变量视为带符号的.
这会影响编译的代码的行为,而不影响库例程的行为.
s等价于signedunsigned将声明为字符的字符常量和变量视为无符号的.
这会影响编译的代码的行为,而不影响库例程的行为.
u等效于unsignedA-80《C++用户指南》2005年1月A.
2.
112-xcheck[=i]SPARC:使用-xcheck=stkovf进行编译将增加对单线程程序中的主线程的栈溢出的运行时检查,并对多线程程序中的从属线程栈的栈溢出执行运行时检查.
如果检测到堆栈溢出,则生成SIGSEGV.
如果应用程序需要以与处理其他地址空间违规不同的方法,来处理堆栈溢出引起的SIGSEGV,那么请参见sigaltstack(2).
值i必须是下列值之一:默认如果未指定-xcheck,则编译器默认为-xcheck=%none.
如果指定没有任何参数的-xcheck,编译器默认为-xcheck=%none.
在命令行上-xcheck选项不进行累积.
编译器按照上次出现的命令设置标志.
A.
2.
113-xchip=c指定供优化器使用的目标处理器.
-xchip选项通过指定目标处理器来指定定时属性.
该选项会影响:指令的顺序(即调度)编译器使用分支的方法语义上等价于其他指令时使用的指令注–该选项可单独使用,但它是-xtarget选项的部分扩展,主要用途是覆盖-xtarget选项提供的值.
表A-28-xcheck值值含义%all执行全部检查.
%none不执行检查.
stkovf打开堆栈溢出检查.
no%stkovf关闭堆栈溢出检查.
附录AC++编译器选项A-81值c必须是下列值之一:表A-29-xchip值平台c的值使用定时属性优化SPARCgeneric可以在多数SPARC处理器上获得高性能native可以在运行编译器的系统上获得高性能old早于SuperSPARC处理器的处理器superSuperSPARC处理器super2SuperSPARCII处理器micromicroSPARC处理器micro2microSPARCII处理器hyperhyperSPARC处理器hyper2hyperSPARCII处理器powerupWeitekPowerUp处理器ultraUltraSPARC处理器ultra2UltraSPARCII处理器ultra2eUltraSPARCIIe处理器ultra2iUltraSPARCIIi处理器ultra3UltraSPARCIII处理器ultra3cuUltraSPARCIIICu处理器ultra3iUltraSparcIIIi处理器.
x86generic多数x86处理器386Intel386处理器486Intel486处理器pentiumIntelPentium处理器pentium_proIntelPentiumPro处理器pentium3IntelPentium3处理器pentium4IntelPentium4处理器A-82《C++用户指南》2005年1月默认在多数SPARC处理器中generic为默认值,指示编译器使用最佳定时属性以获得高性能,而不降低任何处理器的性能.
A.
2.
114-xcode=aSPARC:指定代码地址空间.
注–您应该通过指定-xcode=pic13或-xcode=pic32来生成共享对象.
也可以使用-xarch=v9-xcode=abs64和-xarch=v8、-xcode=abs32生成可用共享对象,但它们效率很低.
用-xarch=v9、-xcode=abs32或-xarch=v9、-xcode=abs44生成的共享对象无法工作.
值a必须是下列值之一:要确定使用-xcode=pic13还是-xcode=pic32,请通过使用elfdump-c查看全局偏移表(GOT)的大小(有关详细信息,请参见elfdump(1)手册页)以及段标题sh_name:.
got.
sh_size值是GOT的大小.
如果GOT小于8,192字节,请指定-xcode=pic13,否则指定-xcode=pic32.
通常,确定应该如何使用-xcode时应遵循以下准则:表A-30-xcode值a的值含义abs32生成快速但有范围限制的32位绝对地址.
代码+数据+bss的大小被限制为2**32字节.
abs44SPARC:生成具有适当速度和范围的44位绝对地址.
代码+数据+bss的大小被限制为2**44字节.
只适用于64位架构:-xarch={v9|v9a|v9b}.
使用动态(共享)库时不要使用此值.
abs64SPARC:生成缓慢但无范围限制的64位绝对地址.
只适用于64位架构:-xarch={v9|v9a|v9|generic64|native64}pic13生成快速但有范围限制的位置独立代码(小模型).
等价于-Kpic.
允许在32位架构上最多引用2**11个唯一的外部符号,而在64位架构上可以最多引用2**10个.
pic32生成缓慢但无范围限制的位置独立代码(大模型).
等价于-KPIC.
允许在32位架构上最多引用2**30个唯一的外部符号,而在64位架构上可以最多引用2**29个.
附录AC++编译器选项A-83如果是生成可执行文件,则不应该使用-xcode=pic13或-xcode=pic32.
如果是生成仅用于链接到可执行文件的归档库,则不应该使用-xcode=pic13或-xcode=pic32.
如果是生成共享库,请先使用-xcode=pic13,一旦GOT大小超过了8,192字节,则使用-xcode=pic32.
如果是生成用于链接到共享库的归档库,则只应该使用-xcode=pic32.
默认对于SPARCV8和V7处理器,默认为-xcode=abs32.
而对于SPARC和UltraSPARC处理器,当您使用-xarch={v9|v9a|v9b|generic64|native64}时,默认为-xcode=abs64.
在SPARC上存在两个具有-xcode=pic13和-xcode=pic32的名义性能成本:取决于设置为指向表(_GLOBAL_OFFSET_TABLE_)的寄存器的入口(该表用于访问共享库全局或静态变量的表),用-xcode=pic13或-xcode=pic32编译的例程会执行一些附加指令.
对全局或静态变量的每次访问都会通过_GLOBAL_OFFSET_TABLE_涉及附加间接内存引用.
如果使用-xcode=pic32完成编译,则在每个全局和静态内存引用中有两个附加指令.
考虑到以上成本时,由于共享库代码的效果,使用-xcode=pic13和-xcode=pic32会显著降低系统内存要求.
编译-xcode=pic13或-xcode=pic32的共享库中的每个代码页面可以由使用该库的每个进程共享.
只要共享库中的代码页面包含了一个非pic(即绝对)内存引用,该页面就是不可共享的,而且每次执行使用该库的程序时必须创建该页面的副本.
要辨别是否已经使用-xcode=pic13或-xcode=pic32编译了.
o文件,最简单的方法是使用nm命令:包含位置独立代码的.
o文件还包含了对_GLOBAL_OFFSET_TABLE_未解决的外部引用,该引用由字母U指示.
要决定是使用-xcode=pic13还是使用-xcode=pic32,请用nm来标识库中使用或定义的不同全局和静态变量的编号.
如果_GLOBAL_OFFSET_TABLE_的大小小于8,192字节,就可以使用-Kpic.
否则,必须使用-xcode=pic32.
警告在不同的步骤中编译和链接时,在编译步骤和链接步骤中必须使用相同的-xarch选项.
%nmfile.
o|grep_GLOBAL_OFFSET_TABLE_U_GLOBAL_OFFSET_TABLE_A-84《C++用户指南》2005年1月A.
2.
115-xcrossfile[=n]SPARC:启用跨源文件的优化和内联处理.
-xcrossfile在编译期间工作并且仅涉及出现在编译命令中的文件.
请参考下列命令行示例:跨模块优化发生在文件f1.
cc和f2.
cc之间,以及f3.
cc和f4.
cc之间.
在f1.
cc和f3.
cc或f4.
cc之间不发生优化.
值n必须是下列值之一:通常,在命令行上编译器的分析范围限制到每个独立的文件.
例如,传递-xO4选项时,自动内联被限制到同一源文件中定义和引用的子程序.
编译器使用-xcrossfile或-xcrossfile=1可以分析在命令行上命名的所有文件,结果就好像这些文件被连接到单一的源文件中.
默认如果未指定-xcrossfile,则假定-xcrossfile=0且不执行任何跨文件优化或内联.
-xcrossfile与-xcrossfile=1相同.
交互-xcrossfile选项只有与-xO4或-xO5一起使用时才有效.
example%CC-xcrossfile-xO4-cf1.
ccf2.
ccexample%CC-xcrossfile-xO4-cf3.
ccf4.
cc表A-31-xcrossfile值n的值含义0不执行跨文件优化或跨文件内联.
1执行多个源文件之间的优化和内联处理.
附录AC++编译器选项A-85警告这种编译所产生的文件由于可能的内联所以是相互依赖的,而且在将这些文件链接到程序时必须作为一个单元使用.
如果更改了任何一个例程并重新编译了文件,则必须重新编译所有的文件.
因此,使用该选项会影响makefile的结构.
另请参见-xldscopeA.
2.
116-xdebugformat=[stabs|dwarf]如在"DWARF调试信息格式"中指定的那样,编译器将调试器信息从stabs格式迁移到dwarf格式.
在此发行版本中,默认设置为-xdebugformat=stabs.
如果要维护读取调试信息的软件,现在您可以使用此选项将工具从stabs格式转换为dwarf格式.
使用此选项可作为一种为移植工具而存取新格式的方法.
除非您要维护读取调试器信息的软件,或者特定工具要求使用这些格式之一的调试器信息,否则没有必要使用此选项.
如果未指定-xdebugformat,则编译器假定-xdebugformat=stabs.
该选项需要一个参数.
此选项影响使用-g选项记录的数据的格式.
即使在没有使用-g的情况下记录少量调试信息,此选项仍可控制其信息格式.
因此,即使不使用-g,-xdebugformat仍有影响.
dbx和性能分析软件理解stabs和dwarf格式,因此使用此选项对所有工具的功能性并无影响.
注–这是过渡性接口,因此发行版本之间会发生更改而不兼容,即使在发行版本更新较少时也是如此.
stabs或dwarf格式的任何特定字段或值的详细资料也在不断改进.
有关详细信息,另请参见dumpstabs(1)和dwarfdump(1)手册页.
表A-32-xdebugformat标志值含义stabs-xdebugformat=stabs生成的调试信息采用stabs标准格式.
dwarf-xdebugformat=dwarf生成的调试信息采用dwarf标准格式.
A-86《C++用户指南》2005年1月A.
2.
117-xdepend=[yes|no](SPARC)分析循环以了解迭代间数据依赖性并执行循环重构.
循环重构包括循环交换、循环合并、标量替换和"死"数组赋值消除.
如果优化级别不是-xO3或更高级别,则编译器将优化级别提高到-xO3并发出警告.
如果您未指定-xdepend,则默认值为-xdepend=no,该值表示编译器不分析循环以了解数据依赖性.
如果您指定-xdepend,但未指定参数,则编译器将此选项设置为-xdepend=yes,该值表示编译器分析循环以了解数据依赖性.
依赖性分析可能有助于单处理器系统.
然而,如果要在单处理器系统上使用-xdepend,则您不应使用-xautopar或-xexplicitpar.
如果使用了二者之一,则对多处理器系统执行-xdepend优化.
A.
2.
118-xdumpmacros[=value[,value.
.
.
]]要查看宏在程序中如何工作时,请使用这个选项.
该选项提供了诸如宏定义、取消定义的宏和宏用法实例的信息,并按宏的处理顺序将输出打印到标准错误(stderr).
-xdumpmacros选项在整个文件结尾之前或在dumpmacros或end_dumpmacrospragma覆盖该选项之前都是有效的.
请参见第B-6页的第B.
2.
5节"#pragmadumpmacros".
值您可以用以下参数代替value:表A-33-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不打印任何宏信息附录AC++编译器选项A-87这些选项值会累积,因此指定-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;#endifA-88《C++用户指南》2005年1月以下示例显示了基于defs、undefs、sys和loc参数的文件t.
c的输出.
example%CC-c-xdumpmacros-DFOOt.
c#define__SunOS_5_71#define__SUNPRO_CC0x570#defineunix1#definesun1#definesparc1#define__sparc1#define__unix1#define__sun1#define__BUILTIN_VA_ARG_INCR1#define__SVR41#define__SUNPRO_CC_COMPAT5#define__SUN_PREFETCH1#defineFOO1#undefFOO#defineCOMPUTE(a,b)a+bexample%CC-c-xdumpmacros=defs,undefs,loc-DFOO-UBARt.
c命令行:#define__SunOS_5_71命令行:#define__SUNPRO_CC0x570命令行:#defineunix1命令行:#definesun1命令行:#definesparc1命令行:#define__sparc1命令行:#define__unix1命令行:#define__sun1命令行:#define__BUILTIN_VA_ARG_INCR1命令行:#define__SVR41命令行:#define__SUNPRO_CC_COMPAT5命令行:#define__SUN_PREFETCH1命令行:#defineFOO1命令行:#undefBARt.
c,line2:#undefFOOt.
c,line3:#defineCOMPUTE(a,b)a+b附录AC++编译器选项A-89以下示例说明了use、loc和conds参数如何报告文件t.
c中的宏的行为:请参考文件y.
c:以下是基于y.
c中的宏从-xdumpmacros=use,loc产生的输出:另请参见要覆盖-xdumpmacros的作用域时,请使用dumpmacrospragma和end_dumpmacrospragma.
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:usedmacroMMexample%caty.
c#defineX1#defineYX#defineZYinta=Z;example%CC-c-xdumpmacros=use,locy.
cy.
c,line4:usedmacroZy.
c,line4:usedmacroYy.
c,line4:usedmacroXA-90《C++用户指南》2005年1月A.
2.
119-xe仅检查语法和语义错误.
指定-xe时,编译器不生成任何对象代码.
-xe的输出被指向stderr.
如果不需要编译器生成对象文件,就可以使用-xe选项.
例如,如果要使用删除代码的方法来确定导致错误消息的原因,使用-xe可以加速编辑、编译周期.
另请参见-cA.
2.
120-xF[=v[,v.
.
.
]]使链接程序能对函数和变量重组以达到最优.
该选项指示编译器将函数和(或)数据变量放置到单独的分段中,这使链接程序(使用链接程序的-M选项指定的映射文件中的方向)能将这些段重组以优化程序性能.
通常,该优化仅在缺页时间构成程序运行时间的一大部分时才有效.
重组变量有助于解决对运行时性能产生负面影响的以下问题:在内存中存放位置很近的无关变量会造成缓存和页的争用.
在内存中存放位置很远的相关变量会造成过大的工作集.
未用到的弱变量副本会造成过大的工作集,从而降低有效数据密度.
重组变量和函数以优化性能,需要执行以下操作:1.
使用-xF进行编译和链接.
2.
关于如何生成函数的映射文件请遵循《程序性能分析工具》手册的说明,而关于如何生成数据的映射文件请遵循《链接程序和库指南》中的说明.
3.
通过使用链接程序的-M选项与新的映射文件重新链接.
4.
在分析器下重新执行以验证是否增强.
附录AC++编译器选项A-91值v可以是下列值中的一个或多个:默认如果未指定-xF,则默认为-xF=%none.
如果指定了没有参数的-xF,则默认为-xF=%none,func.
交互使用-xF=lcldata可以禁止某些地址计算优化,因此如果实验证明它是有效的,则只能使用该标志.
另请参见analyzer(1)、debugger(1)、ld(1)手册页A.
2.
121-xhelp=flags显示了对每个编译器选项的简要描述.
A.
2.
122-xhelp=readme显示了联机readme文件的目录.
在环境变量PAGER中指定的命令标明了readme文件的页数.
如果未设置PAGER,则默认的分页命令为more.
表A-34-xF值值含义[no%]func[不]将函数分段到单独的段中.
[no%]gbldata[不]将全局数据(具有外部链接的变量)分段到单独的段中.
[no%]lcldata[不]将局部数据(具有内部链接的变量)分段到单独的段中.
%all分段函数、全局数据和局部数据.
%none不分段.
A-92《C++用户指南》2005年1月A.
2.
123-xiaSPARC:链接合适的区间运算库并设置适当的浮点环境.
注–C++区间运算库与Fortran编译器中实现的区间运算相兼容.
扩展-xia选项是扩展到-fsimple=0-ftrap=%none-fns=no-library=interval的宏.
如果使用区间并通过为-fsimple、-ftrap、-fns或-library指定不同的标志来覆盖-xia设置的值,则可能导致编译器出现不正确的行为.
交互要使用区间运算库,请包括.
在使用区间运算库时,必须包括以下库之一:libC、Cstd或iostreams.
关于包括这些库的详细信息请参见-library.
警告如果使用了区间并为-fsimple、-ftrap或-fns指定了不同的值,那么您的程序可能会产生错误行为.
C++区间运算处于实验阶段且正在改进.
不同的发行版本具有不同的功能.
另请参见C++IntervalArithmeticProgrammingReference,IntervalArithmeticSolvesNonlinearProblemsWhileProvidingGuaranteedResults(http://www.
sun.
com/forte/info/features/intervals.
html),-libraryA.
2.
124-xinline[=func_spec[,func_spec.
.
.
]]指定在-xO3或更高级别上优化器可以内联哪些用户编写的例程.
附录AC++编译器选项A-93值func_spec必须是下列值之一.
只有使用-xcrossfile[=1],正在编译文件中的例程才会考虑链接.
优化器决定适合内联的例程.
默认如果未指定-xinline选项,则编译器假设-xinline=%auto.
如果指定了没有参数的-xinline=,则不内联任何函数,这与优化的级别无关.
示例要在禁用函数(该函数声明了intfoo())的内联时启用自动内联,请使用要强烈请求声明为intfoo()的函数的内联,并将所有其他函数作为内联的候选,请使用要强烈请求声明为intfoo()的函数的内联,且不允许任何其他函数的内联,请使用表A-35-xinline值func_spec值含义%auto在-xO4或更高的优化级别上启用自动内联此参数告知优化器它可以内联所选择的函数.
注意,如果没有%auto规范,则在命令行上使用-xinline=[no%]func_name.
.
.
指定显式内联时,自动内联正常关闭.
func_name强烈请求优化器内联函数.
如果未将函数声明为extern"C",则必须粉碎func_name的值.
您可以在可执行文件上使用nm命令来查找粉碎的函数名称.
对于已声明为extern"C"的函数,编译器不粉碎名称.
no%func_name如果将列表上的no%作为例程的前缀,则会禁止对该例程的内联.
关于func_name的粉碎名的规则也适用于no%func_name.
example%CC-xO5-xinline=%auto,no%__1cDfoo6F_i_-ca.
ccexample%CC-xO5-xinline=%auto,__1cDfoo6F_i_-ca.
ccexample%CC-xO5-xinline=__1cDfoo6F_i_-ca.
ccA-94《C++用户指南》2005年1月交互-xinline选项对低于-xO3优化级别的函数无效.
若在-xO4或更高级别上,则优化器决定哪些函数应该内联,而无需指定-xinline选项.
若在-xO4或更高级别上,编译器也尝试决定哪些函数内联后可以提高性能.
如果出现以下任一情况,则不内联例程.
不会省略任何警告.
优化级别低于-xO3无法找到例程内联无益或不安全源码不在正被编译的文件中,或者如果使用-xcrossfile[=1],则源码不在命令行上所命名的文件中警告如果使用-xinline强制内联一个函数,实际上就会降低性能.
另请参见-xldscopeA.
2.
125-xipo[={0|1|2}]执行过程间的优化.
-xipo选项通过调用过程间分析传递,来执行部分程序的优化.
与-xcrossfile不同的是-xipo按链接步骤对所有对象文件执行优化,而且优化不只限于编译命令上的源文件.
但是,正如同-xcrossfile,使用-xipo执行的整个程序优化不包括汇编(.
s)源文件.
-xipo选项特别适用于编译和链接较大的多文件应用程序.
用该标志编译的对象文件具有在这些文件内编译的分析信息,这些信息实现了在源码和预编译的程序文件中的过程间分析.
不过,分析和优化只限于用-xipo编译的对象文件,而不扩展到库的对象文件或库.
附录AC++编译器选项A-95值-xipo选项可以具有以下值.
默认如果未指定-xipo,则假定为-xipo=0.
如果仅指定了-xipo,则假定为-xipo=1.
示例以下示例在相同的步骤中编译和链接.
优化器在三个源文件之间执行交叉文件内联.
该操作在链接的最后一步完成,因此源文件的所有编译不必全在单一的编译中完成,而且这些源文件的编译会覆盖许多独立的编译,其中每个编译都会指定-xipo选项.
以下示例在不同的步骤中编译和链接.
在编译步骤中创建的对象文件具有在这些文件内编译的附加分析信息,这样就可以在链接步骤中执行交叉文件优化.
交互-xipo选项要求的最低优化级别为-xO4.
在同一编译器命令行上不能同时使用-xipo选项和-xcrossfile选项.
表A-36-xipo值值含义0不执行过程间的优化1执行过程间的优化2执行过程间的别名分析和内存分配及布局的优化,以提高缓存的性能example%CC-xipo-xO4-oprogpart1.
ccpart2.
ccpart3.
ccexample%CC-xipo-xO4-cpart1.
ccpart2.
ccexample%CC-xipo-xO4-cpart3.
ccexample%CC-xipo-xO4-oprogpart1.
opart2.
opart3.
oA-96《C++用户指南》2005年1月警告在不同的步骤中编译和链接时,必须在两个步骤中都指定-xipo才是有效的.
未使用-xipo编译的对象可以与使用-xipo编译的对象自由链接.
即使使用-xipo进行编译时,库也不参与交叉文件的过程间分析,如以下示例所示.
在该示例中,在one.
cc、two.
cc和three.
cc之间,main.
cc和four.
cc之间执行过程间的优化,而不在main.
cc或four.
cc和mylib.
a中的例程之间执行过程间优化.
(第一个编译可能生成有关未定义符号的警告,但仍可执行过程间优化,因为过程间优化是编译和链接的一个步骤.
)由于在多个文件之间执行优化所需的附加信息,-xipo选项生成了更大的对象文件.
不过,该附加信息不会成为最后可执行的二进制文件的一部分.
可执行程序大小的增加都是由于执行的附加优化导致的.
A.
2.
125.
1何时不使用-xipo=2过程间分析在链接步骤中使用对象文件集合时,编译器试图执行整个程序分析和优化.
对于该对象文件集合中定义的任何函数或子例程foo(),编译器作出以下两个假定:1.
foo()无法在运行时被在该对象文件集合之外定义的其他例程显式调用.
2.
来自该对象文件集合中的任何例程的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()中,从而导致生成错误的结果.
example%CC-xipo-xO4one.
cctwo.
ccthree.
ccexample%CC-xar-omylib.
aone.
otwo.
othree.
o.
.
.
example%CC-xipo-xO4-omyprogmain.
ccfour.
ccmylib.
a附录AC++编译器选项A-97另请参见-xjobsA.
2.
126-xjobs=n指定-xjobs选项用来设定编译器创建多少个进程来完成它的任务.
在多cpu机器上,该选项可以减少生成时间.
目前,-xjobs只在与-xipo一起使用时才有效.
如果指定-xjobs=n,过程间调用优化器在编译不同的文件时会用n作为它能启动的代码生成器实例的最大数.
值必须带值来指定-xjobs.
否则会发出错误诊断并使编译终止.
通常,n的安全值等于1.
5乘以可用处理器的数量.
由于上下文在产生的作业间切换的开销,使用等于可用处理器数量整数倍的值会降低性能.
此外,如果使用很大的数值会耗尽系统资源(如交换空间).
默认出现最合适的实例之前,-xjobs的多重实例在命令行上会互相覆盖.
示例以下示例在有两个处理器的系统上进行编译时比不使用-xjobs选项而使用相同命令进行编译时更为快速.
A.
2.
127-xlang=language[,language]包含适当的运行库,并确保指定语言的正确运行时环境.
值language必须是f77、f90、f95或c99.
example%CC-xipo-xO4-xjobs=3t1.
cct2.
cct3.
ccA-98《C++用户指南》2005年1月f90与f95参数是等价的.
c99参数为使用cc-xc99=%all编译并使用\f3CC\f1链接的对象调用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的对象文件.
要链接Fortran95和Fortran77的对象文件,请使用如下所示的Fortran95驱动程序.
在相同的编译器命令中不能同时使用-xlang选项和-xlic_lib选项.
如果正使用-xlang并且要在Sun性能库中进行链接,那么请使用-library=sunperf.
警告不要同时使用-xnolib和-xlang.
如果使用C++对象来混合并行的Fortran对象,链接行就必须指定-mt标志.
另请参见-library,-staticlibexample%CC-xlang=f95.
.
.
example%f95-xlang=f77.
.
.
附录AC++编译器选项A-99A.
2.
128-xldscope={v}指定-xldscope选项更改用于定义外部符号的默认链接程序作用域.
由于更好的隐藏了实现,所以对默认的更改会产生更快速更安全的共享库和可执行文件.
值v必须是下列值之一:默认如果未指定-xldscope,则编译器假定-xldscope=global.
如果指定了没有任何值的-xldscope,编译器就会产生错误.
出现最合适的实例之前,该选项的多重实例在命令行上会互相覆盖.
警告如果要使客户端覆盖库中的函数,就必须确保该库生成期间函数不生成内联.
如果使用-xinline指定函数名称,如果在可以自动内联的-xO4或更高级别进行编译,如果使用内联说明符,或如果正使用跨文件的优化,那么编译器内联函数.
例如,假定库ABC具有默认的分配器函数,该函数可用于库的客户端,也可在库的内部使用:void*ABC_allocator(size_tsize){returnmalloc(size);}表A-37-xldscope值值含义全局全局链接程序作用域是限制最少的链接程序作用域.
对符号的所有引用都绑定到定义符号的第一个动态装入模块中的定义.
该链接程序作用域是外部符号的当前链接程序作用域.
符号符号链接程序作用域比全局链接程序作用域具有更多的限制.
将对链接的动态装入模块内符号的所有引用绑定到模块内定义的符号.
在模块外部,符号也显示为全局符号.
该链接程序作用域对应于链接程序选项-Bsymbolic.
尽管不能与C++库一起使用-Bsymbolic,但是可以使用不会引起问题的-xldscope=symbolic.
关于链接程序的更多信息,请参见ld(1).
hidden隐藏链接程序作用域具有比符号和全局链接程序作用域更高的限制.
将动态装入模块内的所有引用绑定到该模块内的定义.
符号在模块外部是不可视的.
A-100《C++用户指南》2005年1月如果在-xO4或更高级别生成库,则编译器内联库组件中出现的对ABC_allocator的调用.
如果库的客户端要用自定义的版本替换ABC_allocator,则在调用ABC_allocator的库组件中不能进行该替换.
最终程序将包括函数的不同版本.
生成库时,用__hidden或__symbolic说明符声明的库函数可以内联生成.
假定这些库函数不被客户端覆盖.
请参见第4-2页的第4.
2节"线程局部存储".
用__global说明符声明的库函数不应内联声明,并且应该使用-xinline编译器选项来防止内联.
另请参见-xinline、-xO、-xcrossfileA.
2.
129-xlibmieee在异常情况下,使libm返回数学例程的IEEE754值.
libm的默认行为是兼容XPG.
另请参见《数值计算指南》A.
2.
130-xlibmil内联选定libm库例程用于优化.
注–该选项不影响C++内联函数.
对于部分libm库例程存在可用的内联模板.
该选项为当前使用的浮点选项和平台选择这些内联模板,生成执行速度最快的可执行文件.
交互-fast选项中隐含了这个选项.
附录AC++编译器选项A-101另请参见-fast、《数值计算指南》A.
2.
131-xlibmopt使用优化数学例程的库.
使用此选项时,必须通过指定-fround=nearest使用默认的舍入模式.
该选项使用了优化性能的数学例程库,并且通常会生成运行速度更快的代码.
这样生成的代码可能与普通数学库生成的代码稍有不同,不同之处通常在最后一位上.
该库选项在命令行上的顺序并不重要.
交互-fast选项中隐含了这个选项.
另请参见-fast、-xnolibmopt、-froundA.
2.
132-xlic_lib=sunperf已过时,不使用.
请改为指定-library=sunperf.
有关详细信息,请参见第A-41页的"-library=l[,l.
.
.
]".
A.
2.
133-xlicinfo编译器无提示地忽略该选项.
A.
2.
134-xlinkopt[=level]指示编译器在对象文件中的任何优化上生成的可执行文件或动态库上,执行链接时优化.
这些优化在链接时通过分析对象二进制代码执行.
虽然未重写对象文件,但产生的可执行代码可能与初始对象的代码不同.
A-102《C++用户指南》2005年1月必须至少在部分编译命令中使用-xlinkopt,才能使-xlinkopt在链接时有效.
优化器仍可以在未使用-xlinkopt进行编译的对象二进制文件上执行部分受限的优化.
-xlinkopt优化出现在编译命令行上的静态库代码,但会跳过出现在命令行上的共享(动态)库代码而不对其进行优化.
当生成共享库时(使用-G编译),也可以使用-xlinkopt.
值级别必须将执行的优化级别设置为0、1或2.
各优化级别如下所示:如果在不同的步骤中编译,则-xlinkopt必须同时出现在编译和链接步骤中:example%cc-c-xlinkopta.
cb.
cexample%cc-omyprog-xlinkopt=2a.
o注意,仅当链接编译器时才使用级别参数.
在以上示例中,即使编译对象二进制文件时使用的是隐含的级别1,链接优化器的级别仍然是2.
默认不用级别参数来指定的-xlinkopt隐含了-xlinkopt=1.
交互当编译整个程序并且使用性能分析反馈时,该选项才最有效.
配置会显示代码中最常用和最少用的部分并相应地指导优化器集中其努力方向.
这对大型应用非常重要,因为链接时执行代码地优化放置可以减少指令的高速缓存缺失.
一般来说,编译如下所示:表A-38-xlinkopt值链接优化器设置行为0禁用链接优化器.
(这是默认情况.
)1在链接时根据控制流分析执行优化,其中包括指令缓冲着色和分支优化.
2在链接时执行附加的数据流分析,其中包括终止的代码排除和地址计算简化.
example%cc-oprogt-xO5-xprofile=collect:progfile.
cexample%progtexample%cc-oprog-xO5-xprofile=use:prog-xlinkoptfile.
c附录AC++编译器选项A-103关于使用性能分析反馈的详细信息,请参见第A-128页的第A.
2.
157节"-xprofile=p".
警告使用-xlinkopt编译时,请不要使用-zcompreloc链接程序选项.
注意,使用该选项编译会略微延长链接的时间,也会增加对象文件的大小,但可执行文件的大小保持不变.
使用-xlinkopt和-g编译会将调试信息包括在内,从而增加了可执行文件的大小.
A.
2.
135-xM在命名的C++程序上只运行预处理程序,同时请求该程序生成makefile依赖性并将结果发送到标准输出(关于make文件和依赖的详细信息,请参见make(1)).
示例例如:生成的输出如下:另请参见make(1S)(关于makefile和依赖性的详细信息)#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.
hA-104《C++用户指南》2005年1月A.
2.
136-xM1该选项除了不报告/usr/include头文件的依赖性,也不报告编译器提供的头文件的依赖性之外,与-xM相同.
A.
2.
137-xMergeSPARC:将数据段和文本段合并.
除非使用ld-N进行链接,否则对象文件中的数据为只读并在进程间共享.
另请参见ld(1)手册页A.
2.
138-xmaxopt[=v]此命令将pragmaopt的级别设置为指定的级别.
v是off、1、2、3、4、5之一.
默认值为-xmaxopt=off,该值导致pragmaopt被忽略.
如果指定-xmaxopt而不提供参数,则等价于指定-xmaxopt=5.
如果同时指定了-xO和-xmaxopt,则使用-xO设置的优化级别不能超过-xmaxopt值.
A.
2.
139-xmemalign=ab(SPARC)使用-xmemalign选项用来控制编译器对数据对齐的假设.
通过控制可能会出现非对齐内存访问的代码和出现非对齐内存访问时的处理程序,可以更轻松的将程序移植到SPARC.
指定最大的假定内存对齐和未对齐的数据访问行为.
在a(对齐)和b(行为)之间必须有一个值.
a指定了最大假定内存对齐,而b指定了未对齐的内存访问行为.
对于可在编译时决定对齐的内存访问,编译器会为数据对齐生成适当的装入/存储指令序列.
对于不能在编译时决定对齐的内存访问,编译器必须假定一个对齐以生成所需的装入/存储序列.
如果运行时的实际数据对齐小于指定的对齐,则未对齐的访问尝试(内存读取或写入)生成一个陷阱.
对陷阱的两种可能响应是附录AC++编译器选项A-105操作系统将陷阱转换为SIGBUS信号.
如果程序无法捕捉到信号,则程序终止.
即使程序捕捉到信号,未对齐的访问尝试仍将无法成功.
操作系统通过翻译未对齐的访问并将控制返回给程序(仿佛访问已成功正常结束)来处理陷阱.
值下表列出了-xmemalign的对齐和行为的值默认以下默认值仅适用于-xmemalign选项不出现时:xmemalgin=8i,对于所有v8体系结构.
xmemalign=8s,对于所有v9体系结构.
在出现-xmemalign选项但未给出任何值时,默认值为:xmemalign=1i,对于所有-xarch值.
示例下表说明了如何使用-xmemalign来处理不同的对齐情况.
表A-39-xmemalign的对齐和行为值ab1假定最多1字节对齐.
i解释访问并继续执行.
2假定最多2字节对齐.
s产生信号SIGBUS.
4假定最多4字节对齐.
f仅限-xarch=v9变体:SIGBUS,否则解释访问并继续执行.
对于所有其他-xarch值,f标志等效于i.
8假定最多8字节对齐.
16假定最多16字节对齐表A-40-xmemalign示例命令情况-xmemalign=1s大量未对齐访问导致了自陷处理非常缓慢.
-xmemalign=8i在发生错误的代码中存在偶然的、有目的的、未对齐的访问.
A-106《C++用户指南》2005年1月A.
2.
140-xmodel=[a]通过使用-xmodel选项,编译器可以为Solarisx86平台修改64位对象的格式,且只应为此类对象编译指定此选项.
仅当还指定了-xarch=generic64、-xarch=amd64或-xarch=amd64a时,该选项才有效.
必须是以下值之一:该选项不是累积的,因此编译器根据命令行中最右侧的-xmodel实例来设置模型值.
如果未指定-xmodel,则编译器假定-xmodel=small.
如果指定不带参数的-xmodel,则会出现错误.
不必使用此选项来编译所有转换单元.
只要确保可以找到要访问的对象就可以编译选定的文件.
A.
2.
141-xnativeconnect[=i]注–这是"功能终止"声明.
在以后的SunStudio发行版本中,可能会删除该选项.
-xmemalign=8s程序中应该没有任何未对齐访问.
-xmemalin=2s要检查可能的奇数字节访问.
-xmemalign=2i要检查可能的奇数字节访问并要程序工作.
表A-41-xmodel标志值含义small此选项为小模型生成代码,在此模型中,在链接时已知所执行代码的虚拟地址,并且已知所有符号均位于范围在0至2^31-2^24-1之间的虚拟地址.
kernel为内核模型生成代码,在此模型中,将所有符号定义为位于2^64-2^31和2^64-2^24之间的范围内.
medium为中模型生成代码,在此模型中,没有假定有关数据部分的符号引用的范围.
文本部分的大小和地址与小代码模型具有相同的限制.
表A-40-xmemalign示例命令情况附录AC++编译器选项A-107要将接口信息包括在对象文件及后续共享库内部时,请使用-xnativeconnect选项,这样共享库就可以与用Java编程语言(Java代码)编写的代码接口.
当使用-G生成共享库时,也必须包括-xnativeconnect.
当用-xnativeconnect编译时,可以提供最大的外部可视本地代码接口.
"本地连接器工具"(NativeConnectorTool,NCT)能够自动生成Java代码和Java本地接口(JNI)代码.
一起使用-xnativeconnect和NCT可以使C++共享库中的函数能从Java代码进行调用.
关于如何使用NCT的更多信息请参见联机帮助.
值i必须是下列值之一:默认如果未指定-xnativeconnect,则编译器将选项设置为-xnativeconnect=%none.
如果仅指定了-xnativeconnect,则编译器将选项设置为-xnativeconnect=inlines,interfaces.
该选项不累积.
编译器使用指定的最后一个设置.
例如,如果您指定了:则编译器将选项设置为-xnativeconnect=no%inlines,interfaces.
警告这是"功能终止"声明.
在以后的SunStudio发行版本中,可能会删除该选项.
表A-42-xnativeconnect值值含义%all生成-xnativeconnet各选项所描述的全部不同数据.
%none不生成-xnativeconnet各选项所描述的任何不同数据.
[no%]inlines强制生成已引用内联函数的行外实例.
它提供具有外部可视方法的本机连接器来调用内联函数.
调用点中的函数普通内联不受其影响.
[no%]interfaces强制生成二进制接口描述符(BinaryInterfaceDescriptors,BIDS)CC-xnativeconnect=inlinesfirst.
o-xnativeconnect=interfacessecond.
o-O-G-olibrary.
soA-108《C++用户指南》2005年1月如果计划使用-xnativeconnect,不要用-compat=4进行编译.
记住,如果指定没有参数的-compat,则编译器将其设置为-compat=4.
如果未指定-compat,编译器将其设置为-compat=5.
您还可以通过-compat=5将其显式设置为兼容模式.
A.
2.
142-xnolib禁止链接默认系统库.
通常(不含该选项)情况下,C++编译器会链接多个系统库以支持C++程序.
-llib选项使用这个选项来链接没有传递到ld的默认系统库.
通常情况下,编译器按照以下顺序链接系统支持库:在标准模式(默认模式)下:在兼容模式(-compat)下:-l选项的顺序非常重要.
-lm选项必须出现在-lc之前.
注–如果指定了-mt编译器选项,编译器通常就在链接-lm之前对-lthread进行链接.
要决定在默认情况下链接的系统支持库,请使用-dryrun选项进行编译.
例如,以下命令的输出:在输出中包括了以下内容:-lCstd-lCrun-lm-lc-lC-lm-lcexample%CCfoo.
cc-xarch=v9-dryrun-lCstd-lCrun-lm-lc附录AC++编译器选项A-109示例对于符合C应用程序二进制接口的基本编译(即只支持C所需的C++程序),请使用:要将libm静态链接到具有通用架构指令集合的单线程应用程序,请使用:标准模式下:兼容模式下:交互使用-xarch=v9,-xarch=v9a或-xarch=v9b链接时,某些诸如libm.
a和libc.
a的静态系统库不可用.
如果指定了-xnolib,就必须按给定的顺序手动链接所有需要的系统支持库.
必须最后链接系统支持库.
如果指定了-xnolib,则忽略-library.
警告许多C++语言特性需要使用libC(兼容模式下)或libCrun(标准模式下).
系统支持库的集合不稳定,会因不同的发行版本而更改.
另请参见-library、-staticlib、-lexample%CC-xnolibtest.
cc-lcexample%CC-xnolibtest.
cc-lCstd-lCrun-Bstatic-lm\-Bdynamic-lcexample%CC-compat-xnolibtest.
cc-lC-Bstatic-lm\-Bdynamic-lcA-110《C++用户指南》2005年1月A.
2.
143-xnolibmil在命令行上取消-xlibmil.
将该选项与-fast一起使用以覆盖对优化数学库的链接.
A.
2.
144-xnolibmopt不使用数学例程库.
示例在命令行上-fast选项之后使用该选项,如下例所示:A.
2.
145-xOlevel指定优化级别,注意大写字母O要后跟数字1、2、3、4或5.
通常,程序执行速度取决于优化的级别.
优化级别越高,运行时性能越好.
不过,较高的优化级别会延长编译时间并生成较大的可执行文件.
某些情况下,-xO2的执行可能比其他优化级别好,而-xO3也可能胜过-xO4.
尝试用每个级别编译以查看您是否会遇到这种少见的情况.
如果优化器运行时内存不足,则会尝试在较低的优化等级上重试当前过程来恢复.
优化器在-xOlevel选项中指定的初始级别中恢复随后的过程.
有五个级别可以与-xO一起使用.
以下几节描述了在SPARC平台和x86平台上如何操作这些级别.
值在SPARC平台上:-xO1只执行最小量的优化(peephole),也称为postpass,即汇编级优化.
如果使用-xO2或-xO3导致了过多的编译时间,或者您所使用的交换空间不足,那么可以使用-xO1.
-xO2执行基本的局部和全局优化,其中包括:感应变量消除局部和全局的通用子表达式消除example%CC-fast-xnolibmopt附录AC++编译器选项A-111代数运算简化复制传播常量传播非循环变体优化寄存器分配基本块合并尾部递归消除终止代码消除尾部调用消除复杂表达式扩展该级别不优化外部变量或间接变量的引用或定义.
-O选项与-xO2选项等价.
除了在-xO2级别执行优化外,-xO3还会优化外部变量的引用和定义.
该级别不跟踪指针赋值的结果.
编译volatile没有正确保护的设备驱动程序或编译修改信号处理程序内外部变量的程序时,请使用-xO2.
通常,如果不将该级别与-xspace选项组合,就会增加代码的大小.
-xO4除执行-xO3的优化之外,还自动内联包含在同一文件中的函数.
自动内联通常会提高执行速度,但有时却会使速度变得更慢.
通常,如果不将该级别与-xspace选项组合,就会增加代码的大小.
-xO5生成最高级别的优化.
它只适用于占用大量计算机时间的小部分程序.
该级别采用了占用更多编译时间或无法在某种程度上减少执行时间的优化算法.
如果使用性能分析反馈执行该级别上的优化,则更容易提高性能.
请参见第A-128页的第A.
2.
157节"-xprofile=p".
在x86平台上:-xO1执行基本优化.
其中包括代数运算简化、寄存器分配、基本块合并、终止代码和存储消除以及peephole优化.
-xO2执行局部通用子表达式消除、局部复制传播、常量传播、尾部递归消除和级别1执行的优化.
-xO3执行全局通用子表达式的消除、全局的复制传播和常量传播、循环长度简约、感应变量消除、循环变体优化和级别2执行的优化.
-xO4自动内联包含在同一文件中的函数和级别3执行的优化.
这种自动内联通常会提高执行速度,但有时却会使速度变得更慢.
该级别还释放了通用的框架指针注册(ebp).
通常该级别会增加代码的大小.
-xO5生成最高级别的优化.
该级别采用了占用更多编译时间或无法在某种程度上减少执行时间的优化算法.
交互如果您使用-g或-g0,且优化级别是-xO3或更低,那么编译器会尽力提供几乎全部优化的符号信息.
尾部调用优化和后端内联被禁用.
A-112《C++用户指南》2005年1月如果您使用-g或-g0,且优化级别是-xO4或更高,那么编译器会尽力提供全部优化的符号信息.
使用-g进行调试时不禁止-xO级别,但-xO级别会以某些方法限制-g.
例如,-xO级别的选项会降低调试的公用性,因此无法显示dbx中的变量,但仍可使用dbxwhere命令获取符号回溯.
更多信息请参见《使用dbx调试程序》.
-xcrossfile选项只有与-xO4或-xO5一起使用时才有效.
-xinline选项对低于-xO3优化级别的函数无效.
若在-xO4级别上,则优化器决定哪些函数应该内联,而与是否指定-xinline选项无关.
在-xO4级别,编译器还尝试决定哪些函数内联后可以提高性能.
如果使用-xinline强制内联一个函数,实际上就会降低性能.
默认默认为不优化.
不过,只有不指定优化级别时才使用默认.
如果指定了优化级别,则没有任何选项可以关闭优化.
如果尝试避免设置优化级别,那么请不要指定任何隐含优化级别的选项.
例如,-fast是设置优化级别为-xO5的宏选项.
隐含优化级别的所有其他选项给出优化已设置的警告消息.
不使用任何优化来编译的一种方法是从命令行删除所有选项或创建指定优化级别的文件.
警告如果在-xO3或-xO4级别上优化很大的过程(一个过程具有数千行代码),则编译器会需要非常多的内存.
在这些情况下,机器的性能就会降低.
为了防止性能的降低,请使用limit命令来限制单一进程可使用的虚拟内存大小(请参见csh(1)手册页).
例如,将虚拟内存限制为16MB:如果虚拟内存达到16MB的数据空间,该命令会使优化器尝试恢复.
限制不能大于机器总的可用交换空间,而且要足够的小以允许在大型编译的过程中机器可以正常使用.
数据大小的最佳设置取决于要求的优化程度、真实内存和可用虚拟内存的大小.
要查找实际的交换空间,请键入:swap-l要查找实际的真实内存,请键入:dmesg|grepmemexample%limitdatasize16M附录AC++编译器选项A-113另请参见-xldscope-fast、-xcrossfile=n、-xprofile=p、csh(1)手册页A.
2.
146-xopenmp[=i]SPARC:使用-xopenmp选项启用具有OpenMP指令的显式并行.
实现包括了一组源代码指令、运行时库例程和环境变量.
值下表列出了i的值:默认如果未指定-xopenmp,则编译器将选项设置为-xopenmp=none.
如果指定了没有参数的-xopenmp,则编译器将选项设置为-xopenmp=parallel.
警告在将来的发行版本中,-xopenmp的默认可能更改.
可以通过显式指定适当的优化来避免警告消息.
如果单独进行编译和链接,那么也可以在链接步骤中指定-xopenmp.
这在编译包含OpenMP指令的库时尤其重要.
表A-43-xopenmp值i的值含义parallel启用OpenMPpragma的识别.
低于-xopenmp=parallel的最小优化级别是-x03.
如果需要,编译器就将较低级别的优化更改为-x03,并发出警告.
stubs禁用对OpenMPpragma的识别,链接到存根库例程且不更改优化级别.
如果应用程序对OpenMP运行时库例程执行显式调用,并且要编译该应用程序使其能串行执行,就请使用此选项.
-xopenmp=stubs命令还定义了_OPENMP预处理程序标记.
none禁用对OpenMPpragma的识别,不更改程序的优化级别且不预定义任何预处理程序标记.
A-114《C++用户指南》2005年1月另请参见关于生成多进程应用程序的OpenMPFortran95、C和C++应用程序编程接口(API)的完整摘要,请参见《OpenMPAPI用户指南》.
A.
2.
147-xpagesize=n设置堆栈和堆首选的页面大小.
值n值必须是以下项之一:8K、64K、512K、4M、32M、256M、2G、16G或default.
您必须为目标平台指定有效的页面大小.
如果您不指定有效的页面大小,则运行时请求就会被忽略.
在Solaris操作系统上,可以使用getpagesize(3C)命令来确定页面中的字节数.
Solaris操作系统不保证支持页面大小的请求.
您可以使用pmap(1)或meminfo(2)来决定目标平台的页面大小.
您可以使用pmap(1)或meminfo(2)来决定目标平台的页面大小.
注–该功能只在Solaris8操作系统中可用.
在Solaris8软件上不链接使用该选项编译的程序.
默认如果指定-xpagesize=default,则Solaris操作系统设置页面大小.
扩展该选项其实是代表-xpagesize_heap和-xpagesize_stack的宏.
这两个选项接受与-xpagesize参数相同的参数:8K、64K、512K、4M、32M、256M、2G、16G或default.
可以通过指定-xpagesize来使用相同的值设置这两个选项,或使用不同的值对其进行分别指定.
警告只有在编译时和链接时使用-xpagesize选项,该选项才是有效的.
附录AC++编译器选项A-115另请参见使用该选项进行编译与使用等价的选项将LD_PRELOAD环境变量设置为mpss.
so.
1或在运行程序之前使用等价的选项运行Solaris命令ppgsz(1)具有相同的效果.
详细信息请参见Solaris手册页.
A.
2.
148-xpagesize_heap=n在内存中为堆设置页面大小.
值n可以是8K、64K、512K、4M、32M、256M、2G、16G或default.
您必须为目标平台指定有效的页面大小.
如果不指定有效的页面大小,运行时该请求就会被忽略.
在Solaris操作系统上,可以使用getpagesize(3C)命令来确定页面中的字节数.
Solaris操作系统不保证支持页面大小的请求.
您可以使用pmap(1)或meminfo(2)来确定目标平台上的页面大小.
注–该功能只在Solaris8操作系统中可用.
在Solaris8环境不链接使用该选项编译的程序.
默认如果指定-xpagesize_heap=default,则Solaris操作系统设置页面大小.
警告除非在编译和链接时使用,否则-xpagesize_heap选项无效.
另请参见使用该选项进行编译与使用等价的选项将LD_PRELOAD环境变量设置为mpss.
so.
1或在运行程序之前使用等价的选项运行Solaris命令ppgsz(1)具有相同的效果.
详细信息请参见Solaris手册页.
A-116《C++用户指南》2005年1月A.
2.
149-xpagesize_stack=n在内存中为堆栈设置页面大小.
值n可以是8K、64K、512K、4M、32M、256M、2G、16G或default.
您必须为目标平台指定有效的页面大小.
如果不指定有效的页面大小,运行时该请求就会被忽略.
在Solaris操作系统上,可以使用getpagesize(3C)命令来确定页面中的字节数.
Solaris操作系统不保证支持页面大小的请求.
您可以使用pmap(1)或meminfo(2)来确定目标平台上的页面大小.
注–该功能只在Solaris8操作系统中可用.
在Solaris8软件上不链接使用该选项编译的程序.
默认如果指定-xpagesize_stack=default,则Solaris操作系统设置页面大小.
警告除非在编译和链接时使用,否则-xpagesize_heap选项不会生效.
另请参见使用该选项进行编译与使用等价的选项将LD_PRELOAD环境变量设置为mpss.
so.
1或在运行程序之前使用等价的选项运行Solaris命令ppgsz(1)具有相同的效果.
详细信息请参见Solaris手册页.
A.
2.
150-xpch=v该编译器选项激活了预编译头文件特性.
预编译头文件的作用是减少源代码共享同一组包含文件的应用程序的编译时间,而且这些包含文件往往有大量的源代码.
编译器首先从一个源文件收集一组头文件信息,然后在重新编译该源文件或者其他有同样头文件的源文件时就可以使用这些收集到的信息.
编译器收集的信息存储在预编译头文件中.
要使用这个特性,需要指定-xpch和-xpchstop选项,并同时使用#pragmahdrstop指令.
附录AC++编译器选项A-117另请参见:第A-119页的第A.
2.
151节"-xpchstop=file"第B-8页的第B.
2.
8节"#pragmahdrstop"创建预编译头文件在指定-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.
在创建预编译头文件时,请选取包含所有源文件之间包括文件通用序列的源文件,预编译头文件与这些源文件一起使用.
包括文件的共同序列在这些源文件之间必须是一样的.
切记,在collect模式中只有一个源文件名称的值是合法的.
例如,CC-xpch=collect:foobar.
cc是有效的,而由于CC-xpch=collect:foobar.
ccfoobar.
cc指定了两个源文件,所以它是无效的.
使用预编译头文件指定-xpch=use:pch_filename使用预编译头文件.
您可以将包括文件同一序列中任意数量的源文件指定为用于创建预编译头文件的源文件.
例如,在use模式中的命令可类似于以下命令:CC-xpch=use:foo.
Cpchfoo.
cbar.
ccfoobar.
cc.
如果下列情况为真,就只应使用现有的预编译头文件.
如果以下任意情况都为假,就应该重新创建预编译头文件:用于访问预编译头文件的编译器与创建预编译头文件的编译器相同.
编译器的一个版本创建的预编译头文件可能无法用于另一版本(包括安装的修补程序产生的差异).
除-xpch选项之外,用-xpch=use指定的编译器选项必须与创建预编译头文件时指定的选项相匹配.
用-xpch=use指定的包括头文件的集合与创建预编译头文件时指定的头文件集合是相同的.
用-xpch=use指定的包括头文件的内容与创建预编译头文件时指定的包括头文件的内容是相同的.
当前目录(即发生编译并尝试使用给定预编译头文件的目录)与创建预编译头文件所在的目录相同.
在用-xpch=collect指定的文件中预处理指令(包括#include指令)的初始序列,与在用-xpch=use指定的文件中预处理指令的序列相同.
A-118《C++用户指南》2005年1月要共享多个源文件间的预编译头文件,这些源文件就必须作为标记的初始序列共享包括文件的共同集合.
该标记的初始序列称为可用前缀.
可用前缀必须在使用相同预编译头文件的所有源文件中解释一致.
源文件的可用前缀只能包含注释和以下任意预处理程序指令:#include#if/ifdef/ifndef/else/elif/endif#define/undef#ident(如果相等,按原样传递)#pragma(如果相等)以上任何指令都可以引用宏.
#else、#elif和#endif指令必须在可用前缀内匹配.
在共享预编译头文件的每个文件的可用前缀中,每个相应的#define和#undef指令必须引用相同的符号(例如每个#define必须引用同一个值).
这些指令在每个可用前缀中出现的顺序也必须相同.
每个相应pragma也必须相同,且必须按相同顺序出现在共享预编译头文件的所有文件中.
融入预编译头文件的头文件一定不要违反以下约束.
这里没有定义对违反任意这些约束的程序的编译结果.
头文件一定不要包含函数和变量定义.
头文件一定不要使用__DATE__和__TIME__.
使用预处理宏会产生无法预料的结果.
头文件一定不要包含#pragmahdrstop.
头文件一定不要在可用前缀中使用__LINE__和__FILE__.
头文件可以在包括的头文件中使用__LINE__和__FILE__.
如何修改make文件以下是要将-xpch融入生成中而对make文件进行修改的几种可能方法.
可以通过使用make和dmake的辅助CCFLAGS变量和KEEP_STATE功能来使用隐式make规则.
预编译头文件在独立的步骤中产生.
.
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附录AC++编译器选项A-119您还可以定义自己的编译规则,而无需尝试使用辅助CCFLAGS.
您可以将预编译头文件作为常规编译的副作用,而无需使用KEEP_STATE,但该方法要求显式编译命令.
A.
2.
151-xpchstop=file使用-xpchstop=file选项指定在使用-xpch选项创建预编译头文件时要考虑的最后一个包含文件.
在命令行上使用-xpchstop等价于将hdrstoppragma放置在第一个包括指令之后,该指令引用由cc命令指定的每个源文件中的文件.
在以下示例中,-xpchstop选项指定了预编译头文件的可用前缀以projectheader.
h的包括结束.
因此,privateheader.
h不是可用前缀的一部分.
.
KEEP_STATE:.
SUFFIXES:.
o.
cc%.
o:%.
ccshared.
Cpch$(CCC)-xpch=use:shared$(CCFLAGS)-c$#include#include"projectheader.
h"#include"privateheader.
h".
.
.
example%CC-xpch=collect:foo.
Cpcha.
cc-xpchstop=projectheader.
h-cA-120《C++用户指南》2005年1月另请参见-xpch,pragmahdrstopA.
2.
152-xpg-xpg选项编译自身文件配置代码,为使用gprof的文件配置收集数据.
该选项调用运行时记录机制,该机制会在程序正常终止时生成gmon.
out文件.
注–-xprofile与-xpg相比较而言,指定-xpg更佳.
这两个选项没有准备或使用由另一个选项提供的数据.
可以在64位Solaris平台上使用prof(1)或gprof(1)或者在32位Solaris平台上仅使用gprof来生成性能分析数据,这些性能分析数据包含近似的用户CPU时间.
这些时间是从主要可执行文件中的例程以及共享库(在链接可执行文件时,被指定为链接程序参数)中的例程的PC样例数据(请参见pcsample(2))中获得的.
尚未对其他共享库(使用dlopen(3DL)启动进程后打开的库)进行性能分析.
在32位Solaris系统上,使用prof(1)生成的性能分析数据仅限于可执行文件中的例程.
通过将可执行文件与-xpg相链接并使用gprof(1),可以分析32位共享库.
Solaris10软件不包含使用-p编译的系统库.
因此,在Solaris10平台上收集的性能分析数据不包含系统库例程的调用计数.
警告如果单独进行编译和链接且使用了-xpg进行链接,就要确保使用-xpg进行链接.
另请参见-xprofile=p、analyzer(1)手册页、《性能分析器》手册.
A.
2.
153-xport64[=(v)]使用该选项可以帮助您调试移植到64位环境的代码.
具体来说,该选项会对以下情况提示警告信息:类型的截断(包括指针),符号扩展以及对位包装的更改.
将代码从诸如V7的32位体系结构移植到诸如V9的64位体系结构时,这些更改是很通常的.
附录AC++编译器选项A-121值下表列出了v的有效值:默认如果未指定-xport64,则默认为-xport64=no.
如果指定了-xport64但不指定标志,则默认为-xport64=full.
示例本节提供了可以导致类型截断、符号扩展和对位包装更改的代码示例.
检查64位值的截断在移植到诸如V9的64位架构时,数据可能会被截断.
截断可能会因赋值(初始化时)或显式类型转换而隐式地发生.
两个指针的差异在于typedefptrdiff_t,它在32位模式下是32位整数类型,而在64位模式下是64位整数类型.
将较长的整数类型截断为较小的整型类型会生成警告,如下示例所示.
表A-44-xport64值v的值含义否将代码从32位环境移植到64位环境时,不会生成与该代码移植有关的任何警告.
implicit只生成隐式转换的警告.
显式类型转换出现时不生成警告.
full将代码从32位环境移植到64位环境时,生成了与该代码移植有关的所有警告.
其中包括对64位值的截断警告、根据ISO值的保存规则对64位的符号扩展,以及对位字段包装的更改.
example%cattest1.
cintx[10];intdiff=&x[10]-&x[5];//警告example%CC-c-xarch=v9-Qoptionccfe-xport64=fulltest1.
c"test1.
c",line3:Warning:Conversionof64-bittypevalueto"int"causestruncation.
1Warning(s)detected.
example%A-122《C++用户指南》2005年1月当显式转换导致数据截断时,请使用-xport64=implicit禁用64位编译模式下的截断警告.
在移植到64位架构过程中出现的另一个常见问题是指针的截断.
该问题在C++中始终是错误.
指定-xport64时,诸如将指针转换为引起这种截断的整型的操作,可能会在V9中导致错误诊断.
example%CC-c-xarch=v9-Qoptionccfe-xport64=implicittest1.
c"test1.
c",line3:Warning:Conversionof64-bittypevalueto"int"causestruncation.
1Warning(s)detected.
example%example%cattest2.
cchar*p;intmain(){p=(char*)(((unsignedint)p)&0xFF);//-xarch=v9错误return0;}example%CC-c-xarch=v9-Qoptionccfe-xport64=fulltest2.
c"test2.
c",line3:Error:Cannotcastfromchar*tounsigned.
1Error(s)detected.
example%附录AC++编译器选项A-123检查符号扩展您还可以使用-xport64选项来检查这种情况:标准ISOC值保留的规则允许在无符号整数类型的表达式中进行有符号整数值的符号扩展.
这种符号扩展会产生细微的运行时错误.
example%cattest3.
cinti=-1;voidpromo(unsignedlongl){}intmain(){unsignedlongl;l=i;//警告promo(i);//警告}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.
A-124《C++用户指南》2005年1月检查位字段包装的更改使用-xport64生成对长位字段的警告.
出现这种位字段时,位字段的包装可能会显著更改.
在成功移植到64位架构之前,依赖于假定的任何程序都需要重新检查,该假定与包装位字段的方法有关.
V9中的输出:V7中的输出:example%cattest4.
c#includeunionU{structS{unsignedlongb1:20;unsignedlongb2:20;}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%example%u.
buf[0]=ffffffffff000000u.
buf[1]=0example%u.
buf[0]=fffff000u.
buf[1]=fffff000example%CC-c-xarch=v9-Qoptionccfe-xport64test4.
c"test4.
c",line5:Warning:64-bittypebitfieldmaychangebitfieldpackingwithinstructureorunion.
"test4.
c",line6:Warning:64-bittypebitfieldmaychangebitfieldpackingwithinstructureorunion.
2Warning(s)detected.
example%附录AC++编译器选项A-125警告注意,只有在64位模式下通过指定诸如-arch=generic64或-xarch=v9选项进行编译时才生成警告.
另请参见第A-69页的第A.
2.
105节"-xarch=isa".
A.
2.
154-xprefetch[=a[,a.
.
.
]]SPARC:在支持预取的架构上启用预取指令,这些架构包括UltraSPARCII(-xarch=v8plus、v8plusa、v9plusb、v9、v9a或v9b)a必须是下列值之一:使用-xprefetch,-xprefetch=auto和-xprefetch=yes,编译器就可以将预取指令自由插入到它生成的代码中.
该操作会提高支持预取的架构的性能.
如果正在较大的多处理器上运行计算密集的代码,您会发现使用-xprefetch=latx:factor有很多优点.
该选项指示代码生成器按照指定的因子调节在预取及其相关的装入或存储之间的默认延迟时间.
预取延迟是执行预取指令和预取数据在缓存中可用时间之间的硬件延迟.
编译器决定放置使用预取数据的预取指令和装入或存储指令的距离时,假定预取延迟值.
注–在预取和装入之间假定的延迟可能与在预取和存储之间假定的延迟不同.
表A-45-xprefetch值值含义auto启用预取指令的自动生成no%auto禁用预取指令的自动生成显式(SPARC)启用显式预取宏no%explicit(SPARC)禁用显式预取宏latx:factor按照指定的因子调整编译器假定的预取到装入和预取到存储的延迟.
您只能将此标志与-xprefetch=auto结合使用.
该因子必须是正浮点数或整数.
是已废弃,不使用.
而是使用-xprefetch=auto,explicit.
否已废弃,不使用.
而是使用-xprefetch=no%auto,no%explicit.
A-126《C++用户指南》2005年1月编译器在多个机器和应用程序间调整预取机制以获得最佳性能.
这种调整并非总能达到最优.
对于内存密集的应用程序,尤其是要在较大的多处理器上运行的应用程序,您可以通过增加预取延迟值获得更高的性能.
要增加值,请使用大于1的因子.
在.
5和2.
0之间的值最有可能提供最高的性能.
对于具有完全位于外部缓存内的数据集的应用程序,您可以通过减小预取延迟值来获得更高的性能.
要减小值,请使用小于1的因子.
要使用-xprefetch=latx:factor选项,请在开始时使用接近1.
0的因子值并对应用程序运行性能测试.
然后适当增加或减小该因子,并再次运行性能测试.
获得最优性能之前,可以不断调整因子并运行性能测试.
以很小的增量逐渐增加或减小因子时,前几步中不会看到性能差异,然后会突然出现差异,最后再趋于稳定.
默认如果未指定-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相同.
如果启用了诸如使用-xprefetch或-xprefetch=yes的自动预取,但不指定延迟因子,则假定为-xprefetch=latx:1.
0.
交互该选项会累积而不覆盖.
sun_prefetch.
h头文件提供了指定显式预取指令的宏.
这些预取可能位于对应于宏出现位置的可执行文件中.
要使用显式预取指令,就必须在正确的架构中包括sun_prefetch.
h,或者从编译器命令中排除-xprefetch或使用-xprefetch、-xprefetch=auto,explicit、-xprefetch=explicit或-xprefetch=yes.
如果您调用了宏并包括了sun_prefetch.
头文件,但传递了-xprefetch=no%explicit或-xprefetch=no,那么显式预取将不会出现在可执行文件中.
只有自动预取启用时才可以使用latx:factor.
即,只有像在-xprefetch=yes,latx:factor中一样将它与yes或auto配合使用,才不会忽略latx:factor.
附录AC++编译器选项A-127警告显式预取只应在度量支持的特殊环境下使用.
因为编译器在多个机器和应用程序之间调节预取机制以获得最优性能,所以当性能测试指示性能明显提高时,应该仅使用-xprefetch=latx:factor.
假定的预取延迟在不同发行版本中是不同的.
因此,无论何时切换到不同的发行版本,强烈建议重新测试延迟因子对性能的影响.
A.
2.
155-xprefetch_auto_type=a(SPARC)其中a是[no%]indirect_array_access.
使用此选项可以确定编译器是否以为直接内存访问生成预取的相同方式为由选项-xprefetch_level指示的循环生成间接预取.
如果不指定-xprefetch_auto_type的设置,编译器将把它设置为-xprefetch_auto_type=no%indirect_array_access.
类似-xdepend、-xrestrict和-xalias_level的选项可以影响计算候选间接预取的主动性,进而影响由于更好的内存别名歧义消除信息而发生的自动间接插入的主动性.
A.
2.
156-xprefetch_level[=i]与使用-xprefetch=auto一样,使用新的-xprefetch_level=i选项来控制自动插入的预取指令的攻击性.
编译器更加主动,换句话说,引入了更多更高-xprefetch_level级别的预取.
-xprefetch_level的合适值取决于应用程序中缓存缺失的数量.
较高的-xprefetch_level值有可能提高具有大量缓存缺失的应用程序的性能.
A-128《C++用户指南》2005年1月值i必须是1、2或3之一.
默认当您指定-xprefetch=auto时,默认值为-xprefetch_level=1.
交互只有在支持预取的平台上(v8plus、v8plusa、v9、v9a、v9b、generic64、native64)并且使用-xprefetch=auto和3或更高的优化级别(-xO3)对该选项进行编译时该选项才有效.
A.
2.
157-xprofile=p使用该选项要先收集并保存执行频率的数据,这样您才能使用随后运行的数据以提高性能.
只有将优化指定为-xO2或更高级别时,该选项才有效.
为编译器提供运行时的性能反馈增强了使用高优化级别(如-xO5)进行编译的效果.
为了生成运行时的性能反馈,就必须使用-xprofile=collect编译,然后运行不是典型数据集的可执行文件,最后用最高的优化级别并使用-xprofile=use重新编译.
对多线程应用程序来讲,性能分析数据集合是安全的.
也就是说,对执行自身多任务(-mt)的程序进行文件配置会产生准确的结果.
只有将优化指定为-xO2或更高级别时,该选项才有效.
值p必须是下列值之一:collect[:name]表A-46-xprefecth_level值值含义1启用预取指令的自动生成.
2超出-xprefetch_level=1目标的目标附加循环用于预取插入.
附加预取可以在-xprefetch_level=1插入的预取之外插入.
3超出-xprefetch_level=2目标的目标附加循环用于预取插入.
附加预取可以在-xprefetch_level=2插入的预取之外插入.
附录AC++编译器选项A-129优化器使用-xprofile=use收集并保存执行频率,以便将来使用.
编译器生成测量语句执行频率的代码.
name是被分析的程序的名称.
name是可选的并(如果未为其指定名称)被假定为a.
out.
在运行时,使用-xprofile=collect:name编译的程序会创建子目录name.
profile来保存运行时的反馈信息.
数据将写入该子目录下的文件feedback中.
可以使用$SUN_PROFDATA和$SUN_PROFDATA_DIR环境变量来更改反馈信息的位置.
更多信息请参见交互一节.
如果多次运行程序,那么执行频率数据会累积在feedback文件中,也就是说以前运行的输出不会丢失.
如果单独进行编译和链接,请确保使用-xprofile=collect编译的任何对象文件也使用-xprofile=collect进行链接.
use[:name]使用生成并保存在feedback文件中的执行频率数据来优化程序,该数据由先前执行使用-xprofile=collect编译的程序生成并保存.
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重新编译对象文件时,编译器也不能在反馈目录中找到该对象文件.
所有这些情况都能使编译器释放对象文件及其文件配置数据之间的关联.
因此,在您指定-xprofile=use时,如果对象文件具有文件配置数据但编译器无法将其与对象文件的路径名相关联,那么请使用-xprofile_pathmap选项来标识正确的目录.
请参见第A-131页的第A.
2.
159节"-xprofile_pathmap".
tcov使用新型的tcov进行基本块覆盖分析.
该选项是tcov的新型基本块文件配置.
该选项具有与-xa选项类似的功能,但可以为在头文件中具有源代码或使用C++模板的程序正确收集数据.
代码指令与-xa选项的代码指令类似,但不再生成.
d文件.
相反却生成单一文件,并且该文件的名A-130《C++用户指南》2005年1月称是按照最后的可执行文件命名的.
例如,如果程序在/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.
158-xprofile_ircache[=path](SPARC)使用-xprofile_ircache[=path]及-xprofile=collect|use,通过重用收集阶段保存的编译数据,减少use阶段的编译时间.
附录AC++编译器选项A-131在编译大程序时,由于中间数据的保存,使得使用阶段的编译时间大大减少.
注意,所保存的数据会占用相当大的磁盘空间.
在使用-xprofile_ircache[=path]时,path会覆盖保存缓存文件的位置.
默认情况下,这些文件会作为对象文件保存在同一目录下.
collect和use阶段出现在两个不同目录中时,指定路径才是有用的.
以下是命令的典型序列:A.
2.
159-xprofile_pathmap(SPARC)当您也指定-xprofile=use命令时,请使用-xprofile_pathmap=collect_prefix:use_prefix选项.
当以下两种情况都为真且编译器无法找到用-xprofile=use编译的对象文件的文件配置数据时,请使用-xprofile_pathmap.
使用-xprofile=use编译对象文件所在的目录与先前使用-xprofile=collect编译对象文件所在的目录不同.
对象文件会共享文件配置中的公共基名,但却可以根据它们在不同目录中的位置互相区分.
collect-prefix是目录树的UNIX路径名的前缀,在该目录树中使用-xprofile=collect编译对象文件.
use-prefix是目录树的UNIX路径名的前缀,在该目录树中使用-xprofile=use编译对象文件.
如果指定了-xprofile_pathmap的多个实例,那么编译器将按照这些实例出现的顺序对其进行处理.
在标识了匹配的use-prefix或发现最后指定的use-prefix与对象文件路径名不匹配之前,每个由-xprofile_pathmap的实例指定的use-prefix都会与对象文件路径名进行比较.
A.
2.
160-xregs=r[,r.
.
.
]控制临时寄存器的使用.
如果编译器可以使用更多的寄存器用于临时存储(临时寄存器),那么编译器将能生成速度更快的代码.
该选项使得附加临时寄存器可用,而这些附加寄存器通常是不适用的.
example%CC-xO5-xprofile=collect-xprofile_ircachet1.
cct2.
ccexample%a.
out//运行收集反馈数据example%CC-xO5-xprofile=use-xprofile_ircachet1.
cct2.
ccA-132《C++用户指南》2005年1月值r必须是下列值之一:每个值的含义都取决于-xarch的设置.
表A-47-xregs值r的值含义[no%]appl(SPARC)[不]允许编译器生成将应用程序寄存器用为临时寄存器的代码.
应用程序寄存器是:g2,g3,g4(v8a,v8,v8plus,v8plusa,v8plusb)g2,g3(v9,v9a,v9b)强烈建议使用-xregs=no%appl编译所有系统软件和库.
系统软件(包括共享库)必须为应用程序保留这些寄存器值.
这些值的使用将由编译系统控制,而且在整个应用程序中必须保持一致.
关于SPARC指令集的更多信息,请参见第A-69页的第A.
2.
105节"-xarch=isa".
在SPARCABI中,这些寄存器被描述为应用程序寄存器.
因为需要更少的load和store指令,所以使用这些寄存器可以提高性能.
不过,这样使用会与将寄存器用于其他目的的程序发生冲突.
[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并发出警告.
附录AC++编译器选项A-133默认SPARC默认值为-xregs=appl,float.
除非在-xregs=frameptr中指定-fast或-xO5优化,否则x86默认值为-xregs=no%frameptr.
示例要使用所有可用的临时寄存器编译应用程序,请使用-xregs=appl,float.
要编译对上下文切换敏感的非浮点代码,请使用-xregs=no%appl,no%float.
另请参见SPARCV7/V8ABI,SPARCV9ABIA.
2.
161-xrestrict[=f](SPARC)将指针值函数函数参数视为限定指针.
f必须是以下值之一:该命令行选项可用于其自身,但最佳效果是与优化同时使用.
例如,命令:将文件prog.
c中的所有指针参数视为限定指针.
命令:表A-48-xrestrict值值含义%all整个文件中的所有指针参数均被视为限定的.
%none文件中没有指针参数被视为限定的.
%source只有在主源文件中定义的函数是限定的.
在包含文件中定义的函数不是限定的.
fn[,fn.
.
.
]用逗号隔开的一个或多个函数名称的列表.
如果指定函数列表,则编译器将指定的函数中的指针参数视为限定的;有关详细信息,请参见第A-134页的第A.
2.
161.
1节"限定指针"一节.
%CC-xO3-xrestrict=%allprog.
cc%CC-xO3-xrestrict=agcprog.
ccA-134《C++用户指南》2005年1月将文件prog.
c中函数agc中的所有指针参数视为限定指针.
默认值为%none;指定-xrestrict等价于指定-xrestrict=%source.
A.
2.
161.
1限定指针为使编译器有效地执行循环的并行执行任务,需要确定特定左值是否指定不同的存储区域.
别名是其存储区域相同的左值.
由于需要分析整个程序,因此确定对象的两个指针是否为别名是一个困难而费时的过程.
考虑下面的函数vsq():如果编译器知道指针a和b访问不同的对象,它可以并行化循环不同迭代的执行.
如果通过指针a和b访问的对象中存在重叠,则编译器并行执行循环将会不安全.
在编译时,编译器并不能通过简单地分析vsq()来获悉a和b访问的对象是否重叠;编辑器需要分析整个程序才能获取此信息.
限定指针用来指定哪些指定不同对象的指针,以便编译器可以执行指针别名分析.
以下是函数参数声明为限定指针的函数vsq()的示例:指针a和b声明为限定指针,因此编译器知道a和b指向不同的存储区域.
有了此别名信息,编译器就能够并行化循环.
关键字restrict是类型限定符,类似于volatile,并且仅限定指针类型.
当您使用-xc99=%all(不包括使用-Xs的情况)时,restrict被识别为关键字.
在某些情况下,您可能不希望更改源代码.
您可以通过使用以下命令行选项,指定将指针赋值的函数参数视为限定指针:如果指定函数列表,则指定的函数中的指针参数将被视为限定的;否则,整个C文件中的所有指针参数均被视为限定的.
例如,-xrestrict=vsq是限定带关键字restrict的函数vsq()的第一个示例中给定的指针a和b.
代码样例A-3带两个指针的循环voidvsq(intn,double*a,double*b){inti;for(i=0;iintmain(){(void)printf(inastringappearsas()\n");return0;}example%CC-xtrigraphs=yestrigraphs_demo.
ccexample%a.
out()inastringappearsas(]example%CC-xtrigraphs=notrigraphs_demo.
ccexample%a.
out()inastringappearsas()A-146《C++用户指南》2005年1月A.
2.
172-xustr={ascii_utf16_ushort|no}如果在对象文件中代码包含要被编译器转换成UTF-16字符串的字符串文字,则可以使用该选项.
如果不指定该选项,编译器既不生成、也不识别16位的字符串文字.
该选项使U"ASCII_string"字符串文字处理成无符号短整数的数组.
因为这样的字符串还不属于任何标准,所以该选项的作用是使非标准C++得以识别.
不是所有文件都必须使用该选项编译.
值如果需要支持使用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";constunsignedshort*fun(){returnU"fun"};example%CC-xustr=ascii_utf16_ushortfile.
cc-c附录AC++编译器选项A-147A.
2.
173-xvector[=a]允许自动生成向量库函数调用和/或生成SIMD(SingleInstructionMultipleData,单指令多数据)指令.
使用此选项时,必须通过指定-fround=nearest使用默认的舍入模式.
a等效于以下值:默认默认值为-xvector=%none.
如果指定-xvector,但没有提供标志,则编译器假定-xvector=lib.
交互如果在以前没有指定-xdepend的情况下在命令行上使用-xvector,则-xvector将会触发-xdepend.
如果未指定优化级别或优化级别低于-x03,则-xvector选项还会将优化级别提高到-x03.
在装入步骤中,编译器包含libmvec库.
如果您以单独的命令编译和链接,请确保在链接CC命令中使用-xvector.
A.
2.
174-xvis[={yes|no}](SPARC)在使用VIS指令集软件开发者工具包(VSDK)中定义的汇编语言模板时,可以使用-xvis=[yes|no]命令.
表A-54-xvector标志值含义[no%]lib如果循环内的数学库调用可转换为对等价向量数学例程的单个调用,则允许[禁止]编译器进行此类转换.
此类转换可提高那些循环计数较大的循环的性能.
[no%]simd允许[禁止]编译器直接使用本机x86SSESIMD指令来提高某些循环的性能.
仅当目标体系结构支持SIMD指令时,编译器才会接受此开关.
例如,必须指定-xarch=amd64、-xarch=amd64a或-xarch=generic64.
在指定-xvector=simd时,还必须指定-xO3或更高的优化级别以及-xdepend.
是在以后的发行版本中,该选项可能已过时.
请改为指定-xvector=lib.
否在以后的发行版本中,该选项可能已过时.
请改为指定-xvector=none.
A-148《C++用户指南》2005年1月VIS指令集是SPARCv9指令集的扩展.
尽管UltraSPARC是64位处理器,但在很多情况下数据都限制在8位或16位范围内,特别是多媒体应用程序中.
VIS指令可以用一条指令处理4个16位数据,这个特性使得处理诸如图像、线性代数、信号处理、音频、视频以及网络等新媒体的应用程序的性能大大提高.
默认默认为-xvis=no.
指定-xvis等价于指定-xvis=yes.
另请参见关于VSDK的更多信息,请参见http://www.
sun.
com/processors/vis/.
A.
2.
175-xwe通过返回非零的退出状态,将所有警告转换成错误.
A.
2.
176-Yc,path指定组件c的位置的新路径.
如果已指定组件的位置,则组件的新路径名称为path/component_name.
该选项被传递到ld.
值c必须是下列值之一:表A-55-Y标志值含义P更改cpp的默认目录.
0更改ccfe的默认目录.
a更改fbe的默认目录.
2(SPARC)更改iropt的默认目录.
c(SPARC)更改cg的默认目录.
O(SPARC)更改ipo的默认目录.
附录AC++编译器选项A-149交互您可以在命令行指定多个-Y选项.
如果对任何一个组件应用了多个Y选项,则保留最后一个选项.
另请参见《Solaris链接程序和库指南》A.
2.
177-z[]arg链接编辑器选项.
更多信息请参见ld(1)手册页和《Solaris链接程序和库指南》.
k更改CClink的默认目录.
l更改ld的默认目录.
f更改c++filt的默认目录.
m更改mcs的默认目录.
u(x86)更改ube的默认目录.
i(x86)更改ube_ipa的默认目录.
h(x86)更改ir2hf的默认目录.
A指定目录以搜索所有编译器组件.
如果路径中找不到组件,搜索将转至编译器所安装的目录.
P将路径添加到默认库搜索路径.
将在默认库搜索路径之前搜索此路径.
S更改启动目标文件的默认目录.
表A-55-Y标志(续)值含义A-150《C++用户指南》2005年1月B-1附录BPragma本附录描述了C++编译器pragma.
pragma是编译器指令,允许您为编译器提供附加信息.
该信息可以更改您所控制的编译详细信息.
例如,packpragma影响了结构内的数据布局.
编译器pragma也称为指令.
预处理程序关键字pragma是C++标准的一部分,但pragma的形式、内容和含义对每个编译器是不同的.
C++标准不定义任何pragma.
注–依赖于pragma的代码是不可移植的.
B.
1Pragma形式C++编译器pragma的各种形式如下所示:变量keyword指定了特定的指令;a表示参数.
#pragmakeyword#pragmakeyword(a[,akeyword(a[,a#pragmasunkeywordB-2《C++用户指南》2005年1月B.
1.
1将函数作为Pragma参数进行重载本附录中列出了几个将函数名称作为参数的pragma.
如果重载该函数,则pragma使用其前面的函数声明作为其参数.
考虑以下示例:在本示例中,foo指foo(double),即在pragma前面的foo声明;而bar指bar(int),即唯一声明的bar.
现在,请考虑以下示例,在该示例中再次重载了foo:在本示例中,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_returnintbar(int);intfoo(int);intfoo(double);#pragmadoes_not_read_global_data(foo,bar)intfoo(int);intfoo(double);intbar(int);#pragmadoes_not_read_global_data(foo,bar)附录BPragmaB-3向编译器断言,调用的指定函数不返回.
does_not_write_global_data断言函数的指定列表不直接或间接写入全局数据.
dump_macros提供关于在代码中使用宏的信息.
end_dumpmacros标记dump_macrospragma的结束.
fini将指定函数标记为完成函数.
hdrstop标识预编译头文件的可用源码前缀的结束.
ident将指定字符串放置在可执行文件的.
comment部分.
init将指定函数标记为初始化函数.
no_side_effect表示函数不更改任何持续状态.
pack(n)控制结构偏移的布局.
n的值为数字-0、1、2、4或8,指定了针对任何结构成员的最坏情况的对齐.
rarely_called告知编译器很少调用指定的函数.
returns_new_memory断言每个命名的函数返回新分配的内存的地址,并且该指针的别名与任何其他指针的别名不同.
unknown_control_flow指定了违反程序调用的通用控制流属性的例程列表.
weak定义弱符号绑定.
B-4《C++用户指南》2005年1月B.
2.
1#pragmaalign使用align使列出的变量内存与integer字节对齐,并覆盖默认.
请遵循以下限制:integer必须是大于1小于128且幂为2的整数,有效的值为:1、2、4、8、16、32、64和128.
variable是全局或静态变量,但不可以是局部或类成员变量.
如果指定的对齐比默认小,就使用默认.
Pragma行必须显示在所涉及的变量的声明之前,否则该行被忽略.
在pragma行上涉及但不在下面pragma行的代码中声明的任何变量都被忽略.
以下示例中的变量是正确声明的.
#pragmaalign在名称空间内部使用时,必须使用修整名称.
例如,以下代码中的#pragmaalign语句就是无效的.
要纠正该问题,请将#pragmaalign语句中的a、b和c用它们的修整名称替换.
B.
2.
2#pragmadoes_not_read_global_data该pragma断言了指定的例程不直接或间接读取全局数据.
允许对调用这些例程的代码进行更好的优化.
具体来讲,赋值语句或存储可以围绕这样的调用移动.
#pragmaaligninteger(variable[,variable.
.
.
])#pragmaalign64(aninteger,astring,astruct)intaninteger;staticcharastring[256];structS{inta;char*b;}astruct;namespacefoo{#pragmaalign8(a,b,c)staticchara;staticcharb;staticcharc;}#pragmadoes_not_read_global_data(funcname[,funcname])附录BPragmaB-5指定函数的原型被声明后,该pragma才可用.
如果全局访问的断言不为真,那么程序的行为就是未定义的.
有关pragma如何将重载的函数名称视为参数的详细说明,请参见第B-2页的第B.
1.
1节"将函数作为Pragma参数进行重载".
B.
2.
3#pragmadoes_not_return该pragma向编译器断言,调用指定例程不会返回.
这样编译器可以执行与假定一致的优化.
例如,寄存器生命周期在允许更多优化的调用点终止.
如果指定的函数不返回,程序的行为就是未定义的.
指定函数的原型被声明后,该pragma才是可用的,如以下示例所示:有关pragma如何将重载的函数名称视为参数的详细说明,请参见第B-2页的第B.
1.
1节"将函数作为Pragma参数进行重载".
B.
2.
4#pragmadoes_not_write_global_data该pragma断言了指定的例程列表不直接或间接写入全局数据.
允许对调用这些例程的代码进行更好的优化.
具体来讲,赋值语句或存储可以围绕这样的调用移动.
指定函数的原型被声明后,该pragma才可用.
如果全局访问的断言不为真,那么程序的行为就是未定义的.
有关pragma如何将重载的函数名称视为参数的详细说明,请参见第B-2页的第B.
1.
1节"将函数作为Pragma参数进行重载".
#pragmadoes_not_return(funcname[,funcname])externvoidexit(int);#pragmadoes_not_return(exit)externvoid__assert(int);#pragmadoes_not_return(__assert)#pragmadoes_not_wrtie_global_data(funcname[,funcname])B-6《C++用户指南》2005年1月B.
2.
5#pragmadumpmacros要查看宏在程序中如何工作时,请使用该pragma.
该pragma提供了诸如宏定义、取消定义和用法实例的信息,并按宏的处理顺序将输出打印到标准错误(stderr).
dumpmacrospragma在文件结束或遇到#pragmaend_dumpmacro后生效.
请参见第B-7页的第B.
2.
6节"#pragmaend_dumpmacros".
您可以用以下参数代替value:注–子选项loc、conds和sys是defs、undefs和use选项的限定符.
loc、conds和sys本身并不会产生任何效果.
例如,#pragmadumpmacros=loc,conds,sys是无效的.
dumpmacrospragma与命令行选项具有相同的效果,不过pragma会覆盖命令行选项.
请参见第A-86页的第A.
2.
118节"-xdumpmacros[=value[,value.
.
.
]]".
dumpmacrospragma不嵌套,因此处理#pragmaend_dumpmacros时,以下代码行停止打印宏信息:dumpmacrospragma的效果是累积性的.
以下代码行#pragmadumpmacros(value[,value.
.
.
])值含义defs打印所有宏定义undefs打印所有取消定义的宏use打印关于使用的宏的信息loc打印位置(路径名称和行号)以及defs、undefs和useconds打印在条件指令中使用的宏的信息sys打印系统头文件中所有宏的定义、取消定义和使用的信息#pragmadumpmacros(defs,undefs)#pragmadumpmacros(defs,undefs).
.
.
#pragmaend_dumpmacros#pragmadumpmacros(defs,undefs)#pragmadumpmacros(loc)附录BPragmaB-7具有和以下行相同的效果如果使用选项#pragmadumpmacros=use,no%loc,那么使用的每个宏名称仅打印一次.
如果使用选项#pragmadumpmacros=use,loc,那么每次使用宏时都打印位置和宏名称.
B.
2.
6#pragmaend_dumpmacros该pragma标记dumpmacrospragma的结束,并停止打印关于宏的信息.
如果dumpmacrospragma之后不使用end_dumpmacrospragma,那么dumpmacrospragma在文件结束之前继续生成输出.
B.
2.
7#pragmafini使用fini将identifier标记为完成函数.
这些函数应为void类型,不接受任何参数,并且当程序在程序控制下终止或从内存删除包含的共享对象时被调用.
和初始化函数一样,完成函数按链接编辑器处理的顺序执行.
在源文件中,#pragmafini中指定的函数在该文件中的静态析构函数之后执行.
在pragma中使用标识符之前,请先声明这些标识符.
#pragmadumpmacros(defs,undefs,loc)#pragmaend_dumpmacros#pragmafini(identifier[,identifier.
.
.
])B-8《C++用户指南》2005年1月B.
2.
8#pragmahdrstop将hdrstoppragma嵌入源文件头文件中以标识可用源码前缀的结束.
例如,考虑以下文件:可用源码前缀在c.
h处结束,因此可以在每个文件中的c.
h后插入#pragmahdrstop.
#pragmahdrstop只能显示在源文件(用CC命令指定)的可用前缀的结尾部分.
不在任何包括文件中指定#pragmahdrstop.
请参见第A-116页的第A.
2.
150节"-xpch=v"和第A-119页的第A.
2.
151节"-xpchstop=file".
B.
2.
9#pragmaident使用ident将string放置在可执行文件的.
comment节.
B.
2.
10#pragmainitexample%cata.
cc#include"a.
h"#include"b.
h"#include"c.
h"#include#include"d.
h".
.
.
example%catb.
cc#include"a.
h"#include"b.
h"#include"c.
h"#pragmaidentstring#pragmainit(identifier[,identifier.
.
.
])附录BPragmaB-9使用init将identifier标记为初始化函数.
这些函数应为void类型,不接受任何参数,并且在执行开始构造程序内存映像时调用.
将共享对象带到内存中的操作时,在程序启动或某些动态装入操作(例如dlopen())期间,执行共享对象中的初始化函数.
调用到初始化函数的唯一顺序就是链接编辑器静态和动态处理该函数的顺序.
在源文件中,#pragmainit中指定的函数在该文件中的静态构造函数之后执行.
在pragma中使用标识符之前,请先声明这些标识符.
B.
2.
11#pragmano_side_effect使用no_side_effect以表示函数不更改任何持续状态.
Pragma声明了命名的函数不具有任何副作用.
这意味着函数将返回仅依赖于传递参数的结果.
此外,函数和后面的函数调用:不读取或写入调用点的调用者中可视的程序状态的任何部分.
不执行I/O.
不更改调用点不可视程序状态的任何部分.
编译器执行优化时可以使用该信息.
如果函数具有副作用,执行调用该函数的程序的结果是未定义的.
name参数指定了当前转换单元内函数的名称.
Pragma必须与函数在相同的作用域,并且必须在函数声明之后出现.
pragma必须在函数定义之前.
有关pragma如何将重载的函数名称视为参数的详细说明,请参见第B-2页的第B.
1.
1节"将函数作为Pragma参数进行重载".
B.
2.
12#pragmaoptfuncname指定当前转换单元内部定义的函数的名称.
level的值指定命名的函数的优化级别.
您可以指定优化级别0、1、2、3、4、5.
您可以通过将level设置为0来关闭优化.
必须在pragma之前使用原型或空参数列表声明函数.
pragma则必须对要优化的函数进行定义.
pragma中列出的任何函数的优化级别被降低为值-xmaxopt.
当-xmaxopt=off时,忽略pragma.
#pragmano_side_effect(name[,name.
.
.
])#pragmaoptlevel(funcname[,funcname])B-10《C++用户指南》2005年1月有关pragma如何将重载的函数名称视为参数的详细说明,请参见第B-2页的第B.
1.
1节"将函数作为Pragma参数进行重载".
B.
2.
13#pragmapack(n)使用pack以影响结构成员的包装.
如果存在,n就必须是0或幂为2的数.
不为0的值指示编译器,数据类型使用较小的n字节对齐和平台的自然对齐.
例如,以下指令使得定义在指令之后(和随后的pack指令之前)的所有结构成员对齐不严格超过2字节的边界,即使正常对齐是4或8字节边界.
n为0或省略时,成员对齐还原为自然对齐值.
如果n的值等于或大于平台上最严格的对齐时,指令具有自然对齐的效果.
下表显示了每个平台最严格的对齐.
pack指令应用到下一个pack指令之前的所有结构定义.
如果在具有不同包装的不同转换单元中定义了相同的结构,那么程序会因某种原因而失败.
具体来将,不应该在包括定义预编译库接口的头文件之前使用pack指令.
推荐用法是将pack指令放置在包装结构之前的程序代码中,并在结构之后放置#pragmapack().
#pragmapack([n])#pragmapack(2)表B-1平台上最严格的对齐平台最严格的对齐x864SPARC通用、V7、V8、V8a、V8plus、V8plusa、V8plusb8SPARCV9、V9a、V9b16附录BPragmaB-11在SPARC平台上使用#pragmapack包装比类型的默认对齐更紧密的对齐时,必须为程序的编译和链接指定-misalign选项.
下表显示了整型数据类型的存储大小和默认对齐.
B.
2.
14#pragmararely_called该pragma提示编译器,指定的函数很少被调用.
这样编译器就可以在这种例程的调用点上执行性能分析反馈式优化,而无需性能分析数据收集阶段的开销.
因为该pragma只是建议,所以编译器不执行基于该pragma的任何优化.
只有声明指定的函数原型之后,#pragmararely_called预处理程序指令才是可用的.
以下是#pragmararely_called的示例:表B-2存储大小和默认对齐字节数类型SPARCV8大小,对齐SPARCV9大小,对齐x86大小,对齐bool1,11,11,1char1,11,11,1short2,22,22,2wchar_t4,44,44,4int4,44,44,4long4,48,84,4float4,44,44,4double8,88,88,4longdouble16,816,1612,4指向数据的指针4,48,84,4指向函数的指针4,48,84,4指向成员数据的指针4,48,84,4指向成员函数的指针8,416,88,4#pragmsrarely_called(funcname[,funcname])externvoiderror(char*message);#pragmararely_called(error)B-12《C++用户指南》2005年1月有关pragma如何将重载的函数名称视为参数的详细说明,请参见第B-2页的第B.
1.
1节"将函数作为Pragma参数进行重载".
B.
2.
15#pragmareturns_new_memory该pragma断言了每个命名的函数返回新分配内存的地址,并且指针不具有到其他任何指针的别名.
该信息允许优化器更好地跟踪指针值并明确内存位置.
这样可以改善调度和管线操作.
如果该断言为假,那么执行调用该函数的程序的结果是未定义的.
name参数指定了当前转换单元内函数的名称.
Pragma必须与函数在相同的作用域,并且必须在函数声明之后出现.
pragma必须在函数定义之前.
如果函数被重载,那么该pragma应用到最近定义的函数.
如果最近定义的函数不具有相同的标识符,那么程序出现错误.
有关pragma如何将重载的函数名称视为参数的详细说明,请参见第B-2页的第B.
1.
1节"将函数作为Pragma参数进行重载".
B.
2.
16#pragmaunknown_control_flow使用unknown_control_flow指定违反程序调用的通用控制流属性的例程列表.
例如,从对任何其他例程的任意调用可以遇到对setjmp()的调用后的语句.
该语句由对longjmp()的调用遇到.
因为这种例程使标准流程图分析无效,调用它们的例程不能安全地优化,所以要禁用优化器来编译这些例程.
如果函数名称被重载,那么会选择最近声明的函数.
#pragmareturns_new_memory(name[,name.
.
.
])#pragmaunknown_control_flow(name[,name.
.
.
])附录BPragmaB-13B.
2.
17#pragmaweak使用weak定义弱全局符号.
该pragma主要在源文件中用于生成库.
链接程序在不能解决弱符号时不会发出警告.
weakpragma可以用以下两种形式之一来指定符号:字符串形式.
字符串必须是C++变量或函数的修整名称.
无效修整名称引用的行为是不可预测的.
后端可以或不可以产生无效修整名称引用的错误.
无论是否产生错误,使用无效修整名称时后端的行为都是不可预测的.
标识符形式.
标识符必须是在编译单元中以前声明的C++函数的明确标识符.
标识符形式不能用于变量.
前端(ccfe)遇到无效的标识符引用时将会产生错误消息.
#pragmaweakname在形式#pragmaweakname中,指令生成了name弱符号.
如果链接程序没有找到name的符号定义,将不会出现错误消息,也不会出现符号的多个弱定义的错误消息.
链接程序仅执行第一个遇到的定义.
如果另一个编译单元具有函数或变量的强定义,那么name将链接到该函数或变量.
如果没有name的强定义,那么链接符号将具有值0.
以下指令将ping定义为弱符号.
如果链接程序无法找到名为ping的符号定义,那么不会生成任何错误消息.
#pragmaweakname1=name2在#pragmaweakname1=name2形式中,符号name1成为对name2的弱引用.
如果name1不在其他地方定义,那么name1将具有值name2.
如果name1在其他地方定义,那么链接程序使用该定义并忽略对name2的弱引用.
以下指令指示链接程序解决对bar的任何引用,前提是在程序中的任何位置定义它,否则解决对foo的引用.
#pragmaweakname1[=name2]#pragmaweakping#pragmaweakbar=fooB-14《C++用户指南》2005年1月在标识符形式中,name2必须在当前编译单元中声明和定义.
例如:使用字符串形式时,符号不需要预先声明.
如果以下示例中的_bar和bar都是extern"C",那么函数不需要声明.
不过,bar必须在相同的对象中定义.
重载函数使用标识符形式时,必须在pragma位置的作用域中正好有一个具有指定名称的函数.
尝试与重载函数一起使用#pragmaweak的标识符形式是错误的.
例如:要避免错误,请使用字符串形式,如以下示例所示.
更多信息,请参见《Solaris链接程序和库指南》.
externvoidbar(int){.
.
.
}externvoid_bar(int);#pragmaweak_bar=barextern"C"voidbar(int){.
.
.
}#pragmaweak"_bar"="bar"intbar(int);floatbar(float);#pragmaweakbar//错误,不明确的函数名称intbar(int);floatbar(float);#pragmaweak"__1cDbar6Fi_i_"//使浮点bar(int)为弱符号1术语表ABI请参见应用程序二进制接口.
ANSIC美国国家标准学会定义的C编程语言.
ANSIC与ISO定义相同.
请参见ISO.
ANSI/ISOC++美国国家标准学会和ISOC++编程语言标准.
请参见ISO.
cfrontC++到C的编译器程序,可以将C++转换为C源代码,然后用标准C编译器编译.
ELF文件编译器生成的可执行和链接格式文件.
ISO国际标准化组织.
K&RCBrianKernighan和DennisRitchie在ANSIC之前开发的实际上的C编程语言标准.
locale地理位置和/或语言唯一的一组约定,例如日期、时间和货币格式.
pragma指示编译器执行特定操作的编译器预处理程序指示或特殊的注释.
stab在对象代码中生成的符号表条目.
相同的格式被用在a.
out文件和ELF文件中以包含调试信息.
stack数据存储方法,通过该方法数据可以增加到堆栈顶部或从堆栈顶部删除数据,采用的是后进先出策略.
VTABLE(虚函数表)编译器为包含虚函数的每个类创建的表.
绑定将函数调用与特定函数定义关联.
更一般的说来,将名称与特定的实体关联.
编译器选项更改编译器行为的指令.
例如,-g选项告知编译器生成调试器的数据.
同义字:标志、开关.
变量标识符命名的数据项.
每个变量都具有类型(例如int或void)和作用域.
另见类变量,实例变量,局部变量.
2《C++用户指南》2005年11月标志请参见编译器选项.
捕获为了执行其他操作,而对诸如程序执行等操作的截获.
截获引起微处理器操作的临时中止,并将程序控制转交给另一个源.
成员函数是函数而非数据定义或类型定义的类元素.
抽象方法不包含实现的方法.
抽象类包含一个或多个抽象方法并因此不能被实例化的类.
定义抽象类的目的是为了通过实现抽象方法,使其他类可以扩展抽象类并使其固定.
递增链接程序通过仅将更改后的.
o文件链接到前一个可执行文件来创建新的可执行文件的链接程序.
动态绑定在运行时函数调用到函数体的连接.
有虚函数时才需动态绑定.
也称为后续绑定,运行时绑定.
动态类型由具有不同声明类型的指针或引用访问的对象的实际类型.
动态类型转换将指针或引用从声明的类型转换到与引用到的动态类型一致的任何类型的安全方法.
多继承直接源于多个基类的派生类的继承.
多态引用到对象的指针或引用的动态类型与声明的指针或引用类型不同的能力.
多线程在单或多处理器系统上开发并行应用程序的软件技术.
二进制兼容性链接对象文件的能力,对象文件由某一个发行版本编译,而使用另一个不同发行版本的编译器.
范围操作或定义应用的范围.
方法在某些面向对象的语言中,成员函数的另外一个名称.
符号表示某些程序实体的名称或标签.
符号表程序编译时显示的所有标识符、程序中标识符的位置和属性的列表.
编译器使用该表来解释标识符的使用.
构造函数在创建类对象时编译器自动调用的特殊类成员函数,这样可以确保对象实例变量的初始化.
构造函数必须始终具有与该函数所属的类相同的名称.
请参见析构函数.
关键字在编程语言中具有唯一含义,并且仅在该语言的专用上下文中使用的字.
函数多态请参见函数重载.
函数模板允许编写可以稍后用作模型或模式的单一函数(用于编写相关函数)的机制.
术语表3函数原型描述函数与程序其他部分接口的声明.
函数重载将相同的名称但不同的参数类型和数字赋予不同的函数.
也称为函数多态.
后续绑定请参见动态绑定.
基类请参见继承.
继承面向对象编程的一个功能,使得编程人员可以从现有类(基类)派生新的类(派生类).
有以下三种继承:公共的、受保护的和专用的.
静态绑定在编译期间函数调用到函数体的连接.
也称为预先绑定.
局部变量在块内已知的数据项,但块外代码不可访问.
例如,在方法内定义的任何变量都是局部变量,在方法外部无法使用.
开关请参见编译器选项.
类由命名的数据元素(可以是不同类型的数据元素)和可以和数据一起执行的一组操作组成的用户定义数据类型.
类变量作为一个整体与特定类关联但与类的特定实例不关联的数据项.
类变量在类定义中定义.
类变量也称为静态字段.
另见实例变量.
类模板描述一组类或相关数据类型的模板.
类型使用符号方法的描述.
基本类型是integer和float.
所有其他类型都是从这些基本类型构造的,构造方法有:将基本类型收集到数组或结构中,或增加诸如指针或常量属性等的修饰符.
链接程序连接对象代码和库以形成完整的可执行程序的工具.
幂等头文件属性,在一个转换单元中包括多次与包括一次具有相同效果.
名称空间控制全局名称的作用域的机制,做法是允许全局空间划分为独立的唯一命名的作用域.
名称修整在C++中,大量函数可以共享相同的名称,因此仅用名称并不能很好的区分不同的函数.
编译器通过名称修整解决了这个问题-为函数创建由函数名称和参数的某些组合组成的唯一名称来启用类型安全链接.
名称修整也称为名称装饰.
搬瓦工怎么样?这几天收到搬瓦工发来的邮件,告知香港pccw机房(HKHK_1)即将关闭,这也不算是什么出乎意料的事情,反而他不关闭我倒觉得奇怪。因为目前搬瓦工香港cn2 GIA 机房和香港pccw机房价格、配置都一样,可以互相迁移,但是不管是速度还是延迟还是丢包率,搬瓦工香港PCCW机房都比不上香港cn2 gia 机房,所以不知道香港 PCCW 机房存在还有什么意义?关闭也是理所当然的事情。点击进...
MechanicWeb怎么样?MechanicWeb好不好?MechanicWeb成立于2008年,目前在美国洛杉矶、凤凰城、达拉斯、迈阿密、北卡、纽约、英国、卢森堡、德国、加拿大、新加坡有11个数据中心,主营全托管型虚拟主机、VPS主机、半专用服务器和独立服务器业务。MechanicWeb只做高端的托管vps,这次MechanicWeb上新Xeon W-1290P处理器套餐,基准3.7GHz最高...
弘速云怎么样?弘速云是创建于2021年的品牌,运营该品牌的公司HOSU LIMITED(中文名称弘速科技有限公司)公司成立于2021年国内公司注册于2019年。HOSU LIMITED主要从事出售香港vps、美国VPS、香港独立服务器、香港站群服务器等,目前在售VPS线路有CN2+BGP、CN2 GIA,该公司旗下产品均采用KVM虚拟化架构。可联系商家代安装iso系统。点击进入:弘速云官方网站地址...