编译器设置虚拟内存

设置虚拟内存  时间:2021-01-16  阅读:()

SunMicrosystems,Inc.
www.
sun.
com关于本文档的建议请发到:docfeedback@sun.
comC++用户指南SunStudio8部件号码817-5808-102004年4月,修订A请回收版权所有2004SunMicrosystems,Inc.
,4150NetworkCircle,SantaClara,California95054,U.
S.
A.
保留所有权利.
SunMicrosystems,Inc.
具有与本文档所描述的产品中所含技术相关的知识产权.
需特别指出的是(但不局限于此),这些知识产权中可能包括一项或多项在http://www.
sun.
com/patents上列出的美国专利,以及一项或多项在美国和其它国家(地区)的其它专利或待批的专利申请.
本文档及其相关产品依据限制其使用、复制、分发和反编译的许可证进行分发.
未经Sun及其许可方(如果存在)的事先书面授权,不得以任何形式、任何手段复制本文档或产品的任何部分.
第三方软件(包括字体技术)的版权归Sun供应商所有并由他们授权.
该产品的部分内容可能出自BerkeleyBSD系统,由加州大学(UniversityofCalifornia)授权.
UNIX是在美国和其它国家(地区)的注册商标,由X/OpenCompany,Ltd.
独家授权.
Sun、SunMicrosystems、Sun徽标、Forte、Java、Solaris、iPlanet、NetBeans以及docs.
sun.
com是SunMicrosystems,Inc.
在美国和其它国家(地区)的商标或注册商标.
所有的SPARC商标均需获得授权才能使用,它们是SPARCInternational,Inc.
在美国和其它国家(地区)的商标或注册商标.
带有SPARC商标的产品所基于的体系结构是由SunMicrosystems,Inc开发的.
Netscape和NetscapeNavigator是NetscapeCommunicationsCorporation在美国和其它国家(地区)的商标或注册商标.
Sunf90/f95的部分内容出自CrayCF90(CrayInc.
的产品).
libdwarf和lidredblack在2000年注册的版权归SiliconGraphicsInc.
所有,您可以依据GNULesserGeneralPublicLicense从http://www.
sgi.
com获得.
本文档按"原样"提供,对所有明示或默示的条件、陈述和担保,包括对适销性、特殊用途的适用性或非侵权性的默示保证,均不承担任何责任,除非此免责声明的适用范围在法律上无效.
iii目录开始之前开始之前开始之前开始之前xxvii本书的结构xxvii排版惯例xxviiiShell提示符xxix访问SunStudio软件和手册页xxix访问编译器和工具文档xxxi访问相关的Solaris文档xxxiii访问相关的C++手册页xxxiii其它公司出版的书籍xxxiv开发人员资源xxxv与Sun技术支持联系xxxv发送意见xxxv第I部分C++编译器1.
C++编译器1–11.
1标准的符合性1–11.
2C++自述文件1–21.
3手册页1–21.
4许可1–3ivC++用户指南2004年4月1.
5C++编译器的新特性1–31.
5.
1一般增强1–31.
5.
2更快的编译:1–51.
5.
3更便捷的移植1–61.
5.
4改进的性能1–71.
5.
5增加的警告和错误控制1–81.
6C++公用程序1–91.
7本地语言支持1–92.
使用C++编译器2–12.
1入门2–12.
2调用编译器2–32.
2.
1命令语法2–32.
2.
2文件名称约定2–42.
2.
3使用多个源文件2–42.
3使用不同编译器版本进行编译2–52.
4编译和链接2–62.
4.
1编译和链接序列2–62.
4.
2分别编译和链接2–62.
4.
3一致编译和链接2–72.
4.
4为SPARCV9编译2–82.
4.
5诊断编译器2–82.
4.
6了解编译器的组织2–92.
5预处理指令和名称2–102.
5.
1Pragmas2–102.
5.
2具有可变数量参数的宏2–102.
5.
3预定义的名称2–112.
5.
4#error2–11目录v2.
6内存要求2–112.
6.
1交换空间大小2–112.
6.
2增加交换空间2–122.
6.
3虚拟内存的控制2–122.
6.
4内存要求2–132.
7简化命令2–132.
7.
1在CShell中使用别名2–132.
7.
2使用CCFLAGS来指定编译选项2–142.
7.
3使用make2–143.
使用C++编译器选项3–13.
1语法3–13.
2通用指南3–23.
3按功能总结的选项3–23.
3.
1代码生成选项3–33.
3.
2编译时性能选项3–33.
3.
3调试选项3–43.
3.
4浮点选项3–53.
3.
5语言选项3–53.
3.
6库选项3–63.
3.
7许可证选项3–73.
3.
8废弃的选项3–73.
3.
9输出选项3–73.
3.
10运行时性能选项3–93.
3.
11预处理程序选项3–103.
3.
12文件配置选项3–103.
3.
13参考选项3–113.
3.
14源文件选项3–113.
3.
15模板选项3–113.
3.
16线程选项3–12viC++用户指南2004年4月第II部分编写C++程序4.
语言扩展4–14.
1链接程序作用域4–24.
2线程局部存储4–34.
3用限制较少的虚函数覆盖4–34.
4生成enum类型和变量的向前声明4–44.
5使用不完整enum类型4–44.
6将enum名称用为作用域限定符4–54.
7使用匿名struct声明4–54.
8传递匿名类实例的地址4–64.
9将静态名称空间作用域函数声明为类友元4–74.
10使用函数名称的预定义__func__符号4–85.
程序组织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–36.
2.
1类模板声明6–36.
2.
2类模板定义6–3目录vii6.
2.
3类模板成员定义6–46.
2.
4类模板的用法6–56.
3模板实例化6–66.
3.
1隐式模板实例化6–66.
3.
2显式模板实例化6–66.
4模板组合6–86.
5缺省模板参数6–86.
6模板专用化6–96.
6.
1模板专用化声明6–96.
6.
2模板专用化定义6–96.
6.
3模板专用化使用和实例化6–106.
6.
4部分专用化6–106.
7模板问题部分6–116.
7.
1非本地名称解析和实例化6–116.
7.
2作为模板参数的本地类型6–126.
7.
3模板函数的友元声明6–136.
7.
4在模板定义内使用限定名称6–156.
7.
5嵌套模板声明6–156.
7.
6引用静态变量和静态函数6–166.
7.
7在同一目录中使用模板生成多个程序6–167.
编译模板7–17.
1冗余编译7–17.
2模板实例化7–17.
2.
1生成的实例7–17.
2.
2整个类实例化7–27.
2.
3编译时实例化7–27.
2.
4模板实例的放置和链接7–2viiiC++用户指南2004年4月7.
3外部实例7–37.
3.
1静态实例7–47.
3.
2全局实例7–57.
3.
3显式实例7–57.
3.
4半显式实例7–57.
4模板系统信息库7–67.
4.
1系统信息库结构7–67.
4.
2写入模板系统信息库7–67.
4.
3从多模板系统信息库读取7–67.
4.
4共享模板系统信息库7–77.
4.
5模板实例自动与-instance=extern一致7–77.
5模板定义搜索7–77.
5.
1源文件位置约定7–77.
5.
2定义搜索路径7–87.
6模板选项文件7–87.
6.
1注释7–87.
6.
2包括7–87.
6.
3源文件扩展名7–97.
6.
4定义源位置7–97.
6.
5模板专用化条目7–118.
异常处理8–18.
1同步和异步异常8–18.
2指定运行时错误8–28.
3禁用异常8–28.
4使用运行时函数和预定义的异常8–38.
5将异常与信号和Setjmp/Longjmp混合8–48.
6生成具有异常的共享库8–5目录ix9.
类型转换操作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–510.
改善程序性能10–110.
1避免临时对象10–110.
2使用内联函数10–210.
3使用缺省运算符10–210.
4使用值类10–310.
4.
1选择直接传递类10–410.
4.
2在不同的处理器上直接传递类10–410.
5缓存成员变量10–511.
生成多线程程序11–111.
1生成多线程程序11–111.
1.
1表明多线程编译11–211.
1.
2与线程和信号一起使用C++支持库11–211.
2在多线程程序中使用异常11–211.
3在线程之间共享C++标准库对象11–311.
4在多线程环境中使用传统iostream11–611.
4.
1多线程安全的iostream库的组织11–611.
4.
2接口更改为iostream库11–1311.
4.
3全局和静态数据11–1511.
4.
4序列执行11–16xC++用户指南2004年4月11.
4.
5对象锁定11–1611.
4.
6多线程安全类11–1811.
4.
7对象析构11–1911.
4.
8示例应用程序11–20第III部分库12.
使用库12–112.
1C库12–112.
2C++编译器提供的库12–212.
2.
1C++库描述12–312.
2.
2访问C++库的手册页12–412.
2.
3缺省C++库12–512.
3相关的库选项12–512.
4使用类库12–612.
4.
1iostream库12–612.
4.
2complex库12–812.
4.
3链接C++库12–912.
5静态链接标准库12–1012.
6使用共享库12–1112.
7替换C++标准库12–1212.
7.
1可以替换的内容12–1212.
7.
2不可以替换的内容12–1312.
7.
3安装替换库12–1312.
7.
4使用替换库12–1312.
7.
5标准头文件实现12–1413.
使用C++标准库13–113.
1C++标准库头文件13–213.
2C++标准库手册页13–313.
3STLport13–14目录xi14.
使用传统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–714.
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的iostreams14–1014.
4创建iostreams14–1114.
4.
1处理使用类fstream的文件14–1114.
5iostream的赋值14–1414.
6格式控制14–1414.
7控制器14–1414.
7.
1使用无格式控制器14–1614.
7.
2参数化控制器14–1714.
8Strstreams:数组的iostreams14–1814.
9Stdiobufs:stdio文件的iostreams14–1814.
10流缓冲14–1814.
10.
1和流缓冲一起使用14–1914.
10.
2使用流缓冲14–1914.
11iostream手册页14–2014.
12iostream术语14–21xiiC++用户指南2004年4月15.
使用复数运算库14–115.
1复数库14–115.
1.
1使用复数库14–215.
2类型complex14–215.
2.
1类complex的构造函数14–215.
2.
2算法运算符14–315.
3数学函数14–415.
4错误处理14–515.
5输入和输出14–615.
6混合模式运算14–715.
7效率14–815.
8复数手册页14–816.
生成库15–116.
1了解库15–116.
2生成静态(归档)库15–216.
3生成动态(共享)库15–316.
4生成包含异常的共享库15–316.
5生成专用的库15–416.
6生成公用的库15–416.
7生成具有CAPI的库15–416.
8使用dlopen从C程序访问C++库15–5第IV部分附录A.
C++编译器选项编译器选项编译器选项编译器选项17–1Q.
1选项信息的结构17–2Q.
2选项参考17–3Q.
2.
1-38617–3Q.
2.
2-48617–3目录xiiiQ.
2.
3-a17–3Q.
2.
4-Bbinding17–3Q.
2.
5-c17–5Q.
2.
6-cg{89|92}17–5Q.
2.
7-compat[={4|5}]17–6Q.
2.
8+d17–7Q.
2.
9-D[]name[=def]17–8Q.
2.
10-d{y|n}17–10Q.
2.
11-dalign17–11Q.
2.
12-dryrun17–11Q.
2.
13-E17–11Q.
2.
14+e{0|1}17–12Q.
2.
15-erroff[=t]17–13Q.
2.
16-errtags[=a]17–14Q.
2.
17-errwarn[=t]17–15Q.
2.
18-fast17–16Q.
2.
19-features=a[,a.
.
.
]17–18Q.
2.
20-filt[=filter[,filter.
.
.
]]17–22Q.
2.
21-flags17–24Q.
2.
22-fnonstd17–24Q.
2.
23-fns[={yes|no}]17–25Q.
2.
24-fprecision=p17–26Q.
2.
25-fround=r17–27Q.
2.
26-fsimple[=n]17–28Q.
2.
27-fstore17–29Q.
2.
28-ftrap=t[,t.
.
.
]17–30Q.
2.
29-G17–31Q.
2.
30-g17–32xivC++用户指南2004年4月Q.
2.
31-g017–33Q.
2.
32-H17–33Q.
2.
33-h[]name17–34Q.
2.
34-help17–34Q.
2.
35-Ipathname17–34Q.
2.
36-I-17–35Q.
2.
37-i17–37Q.
2.
38-inline17–37Q.
2.
39-instances=a17–37Q.
2.
40-instlib=filename17–38Q.
2.
41-KPIC17–39Q.
2.
42-Kpic17–40Q.
2.
43-keeptmp17–40Q.
2.
44-Lpath17–40Q.
2.
45-llib17–40Q.
2.
46-libmieee17–41Q.
2.
47-libmil17–41Q.
2.
48-library=l[,l.
.
.
]17–41Q.
2.
49-mc17–45Q.
2.
50-migration17–46Q.
2.
51-misalign17–46Q.
2.
52-mr[,string]17–47Q.
2.
53-mt17–47Q.
2.
54-native17–48Q.
2.
55-noex17–48Q.
2.
56-nofstore17–48Q.
2.
57-nolib17–48Q.
2.
58-nolibmil17–48目录xvQ.
2.
59-noqueue17–49Q.
2.
60-norunpath17–49Q.
2.
61-O17–49Q.
2.
62-Olevel17–49Q.
2.
63-ofilename17–49Q.
2.
64+p17–50Q.
2.
65-P17–51Q.
2.
66-p17–51Q.
2.
67-pentium17–51Q.
2.
68-pg17–51Q.
2.
69-PIC17–52Q.
2.
70-pic17–52Q.
2.
71-pta17–52Q.
2.
72-ptipath17–52Q.
2.
73-pto17–52Q.
2.
74-ptr17–53Q.
2.
75-ptv17–53Q.
2.
76-Qoptionphaseoption[,option…]17–53Q.
2.
77-qoptionphaseoption17–54Q.
2.
78-qp17–54Q.
2.
79-Qproducesourcetype17–54Q.
2.
80-qproducesourcetype17–55Q.
2.
81-Rpathname[:pathname…]17–55Q.
2.
82-readme17–56Q.
2.
83-S17–56Q.
2.
84-s17–56Q.
2.
85-sb17–56Q.
2.
86-sbfast17–56xviC++用户指南2004年4月Q.
2.
87-staticlib=l[,l.
.
.
]17–56Q.
2.
88-temp=path17–58Q.
2.
89-template=opt[,opt.
.
.
]17–59Q.
2.
90-time17–60Q.
2.
91-Uname17–60Q.
2.
92-unroll=n17–61Q.
2.
93-V17–61Q.
2.
94-v17–61Q.
2.
95-vdelx17–61Q.
2.
96-verbose=v[,v…]17–62Q.
2.
97+w17–63Q.
2.
98+w217–63Q.
2.
99-w17–64Q.
2.
100-Xm17–64Q.
2.
101-xa17–64Q.
2.
102-xalias_level[=n]17–65Q.
2.
103-xar17–67Q.
2.
104-xarch=isa17–68Q.
2.
105-xbuiltin[={%all|%none}]17–72Q.
2.
106-xcache=c17–73Q.
2.
107-xcg8917–74Q.
2.
108-xcg9217–74Q.
2.
109-xchar[=o]17–74Q.
2.
110-xcheck[=i]17–76Q.
2.
111-xchip=c17–76Q.
2.
112-xcode=a17–78Q.
2.
113-xcrossfile[=n]17–79Q.
2.
114-xdumpmacros[=value[,value.
.
.
]]17–81目录xviiQ.
2.
115-xe17–85Q.
2.
116-xF[=v[,v.
.
.
]]17–85Q.
2.
117-xhelp=flags17–86Q.
2.
118-xhelp=readme17–86Q.
2.
119-xia17–87Q.
2.
120-xildoff17–88Q.
2.
121-xildon17–88Q.
2.
122-xinline[=func_spec[,func_spec.
.
.
]]17–88Q.
2.
123-xipo[={0|1|2}]17–90Q.
2.
124-xjobs=n17–92Q.
2.
125-xlang=language[,language]17–93Q.
2.
126-xldscope={v}17–94Q.
2.
127-xlibmieee17–96Q.
2.
128-xlibmil17–96Q.
2.
129-xlibmopt17–97Q.
2.
130-xlic_lib=sunperf17–97Q.
2.
131-xlicinfo17–98Q.
2.
132-xlinkopt[=level]17–98Q.
2.
133-xM17–100Q.
2.
134-xM117–100Q.
2.
135-xMerge17–101Q.
2.
136-xmemalign=ab17–101Q.
2.
137-xnativeconnect[=i]17–102Q.
2.
138-xnolib17–103Q.
2.
139-xnolibmil17–105Q.
2.
140-xnolibmopt17–105Q.
2.
141-xOlevel17–106Q.
2.
142-xopenmp[=i]17–109xviiiC++用户指南2004年4月Q.
2.
143-xpagesize=n17–110Q.
2.
144-xpagesize_heap=n17–111Q.
2.
145-xpagesize_stack=n17–111Q.
2.
146-xpch=v17–112Q.
2.
147-xpchstop=file17–115Q.
2.
148-xpg17–116Q.
2.
149-xport64[=(v)]17–116Q.
2.
150-xprefetch[=a[,a.
.
.
]]17–120Q.
2.
151-xprefetch_level[=i]17–122Q.
2.
152-xprofile=p17–123Q.
2.
153-xprofile_ircache[=path]17–125Q.
2.
154-xprofile_pathmap17–125Q.
2.
155-xregs=r[,r.
.
.
]17–126Q.
2.
156-xs17–127Q.
2.
157-xsafe=mem17–127Q.
2.
158-xsb17–128Q.
2.
159-xsbfast17–128Q.
2.
160-xspace17–128Q.
2.
161-xtarget=t17–128Q.
2.
162-xthreadvar[=o]17–135Q.
2.
163-xtime17–136Q.
2.
164-xtrigraphs[={yes|no}]17–136Q.
2.
165-xunroll=n17–138Q.
2.
166-xustr={ascii_utf16_ushort|no}17–138Q.
2.
167-xvis[={yes|no}]17–139Q.
2.
168-xwe17–139Q.
2.
169-z[]arg17–140目录xixB.
Pragma18–1R.
1Pragma形式18–1R.
2Pragma参考18–2R.
2.
1#pragmaalign18–3R.
2.
2#pragmadoes_not_read_global_data18–4R.
2.
3#pragmadoes_not_return18–4R.
2.
4#pragmadoes_not_write_global_data18–5R.
2.
5#pragmadumpmacros18–5R.
2.
6#pragmaend_dumpmacros18–6R.
2.
7#pragmafini18–7R.
2.
8#pragmahdrstop18–7R.
2.
9#pragmaident18–8R.
2.
10#pragmainit18–8R.
2.
11#pragmano_side_effect18–8R.
2.
12#pragmapack(n)18–9R.
2.
13#pragmararely_called18–10R.
2.
14#pragmareturns_new_memory18–11R.
2.
15#pragmaunknown_control_flow18–11R.
2.
16#pragmaweak18–11术语表术语表术语表术语表术语表术语表术语表术语表–1索引索引索引索引索引索引索引索引–1xxC++用户指南2004年4月xxi表表P-1排版惯例xxviii表P-2代码惯例xxviii表2-1C++编译器识别的文件名称后缀2–4表2-2C++编译系统的组件2–9表3-1选项语法格式示例3–1表3-2代码生成选项3–3表3-3编译时性能选项3–3表3-4调试选项3–4表3-5浮点选项3–5表3-6语言选项3–5表3-7库选项3–6表3-8许可证选项3–7表3-9废弃的选项3–7表3-10输出选项3–7表3-11运行时性能选项3–9表3-12预处理程序选项3–10表3-13文件配置选项3–10表3-14参考选项3–11表3-15源文件选项3–11表3-16模板选项3–11xxiiC++用户指南2004年4月表3-17线程选项3–12表4-1声明说明符4–2表10-1在不同架构上结构和联合的传递10–4表11-1iostream初始核心类11–7表11-2多线程安全的可重入公共函数11–8表12-1C++编译器附带的库12–2表12-2链接C++库的编译器选项12–9表12-3头文件搜索示例12–15表13-1C++标准库头文件13–2表13-2C++标准库手册页13–3表14-1iostream例程头文件14–3表14-2iostream预定义的控制器14–15表14-3iostream手册页概述14–20表14-4iostream术语14–21表15-1复数运算库函数14–4表15-2复数数学函数和三角函数14–4表15-3复数运算库函数的缺省错误处理14–6表15-4类型complex的手册页14–8表Q-1选项语法格式示例17–1表Q-2选项子节17–2表Q-3预定义的宏17–9表Q-4-erroff值17–13表Q-5-errwarn值17–15表Q-6-fast扩展17–16表Q-7兼容模式和标准模式的-features值17–18表Q-8仅用于标准模式的-features值17–19表Q-9仅用于兼容模式的-features值17–20表Q-10-filt值17–22表Q-11-fns值17–25表Q-12-fprecision值17–26表xxiii表Q-13-fround值17–27表Q-14-fsimple值17–28表Q-15-ftrap值17–30表Q-16-instances值17–38表Q-17用于兼容模式的-library值17–42表Q-18用于标准模式的-library值17–42表Q-19-Qoption值17–53表Q-20-Qproduce值17–55表Q-21-staticlib值17–57表Q-22-template值17–59表Q-23-verbose值17–62表Q-24SPARC平台的-xarch值17–68表Q-25IA平台的-xarch值17–71表Q-26-xcache的值17–73表Q-27-xchar值17–75表Q-28-xcheck值17–76表Q-29-xchip值17–77表Q-30-xcode值17–78表Q-31-xcrossfile值17–80表Q-32-xdumpmacros值17–81表Q-33-xF值17–86表Q-34-xinline值17–89表Q-35-xipo值17–91表Q-36-xldscope值17–95表Q-37-xlinkopt值17–99表Q-38-xmemalign的对齐和行为值17–101表Q-39-xmemalign示例17–102表Q-40-xnativeconnect值17–103表Q-41-xopenmp值17–109表Q-42-xport64值17–116xxivC++用户指南2004年4月表Q-43-xprefetch值17–120表Q-44-xprefecth_level值17–122表Q-45-xregs值17–126表Q-46SPARC平台的-xtarget值17–129表Q-47-xtarget的SPARC平台名称17–130表Q-48IA平台的-xtarget值17–134表Q-49Intel架构上的-xtarget扩展17–134表Q-50-xthreadvar的值17–135表Q-51-xtrigraphs值17–137表R-1平台上最严格的对齐18–9表R-2存储大小和缺省对齐字节数18–10xxv编码范例编码范例6-1本地类型用作模板参数问题的示例6-12编码范例6-2友元声明问题的示例6-13编码范例7-1冗余定义条目7-9编码范例7-2静态数据成员的定义和简单名称的用法7-10编码范例7-3模板成员函数定义7-10编码范例7-4不同源文件中模板函数的定义7-10编码范例7-5nocheck选项7-11编码范例7-6special条目7-11编码范例7-7何时应使用special条目的示例7-12编码范例7-8重载special条目7-12编码范例7-9专用化模板类7-12编码范例7-10专用化静态模板类成员7-13编码范例11-1检查错误状态11-9编码范例11-2调用gcount11-10编码范例11-3用户定义的I/O操作11-11编码范例11-4禁用多线程安全11-12编码范例11-5切换到多线程不安全11-12编码范例11-6在多线程不安全的对象中使用同步11-12编码范例11-7新增类11-13编码范例11-8新增类的分层结构11-13xxviC++用户指南2004年4月编码范例11-9新增函数11-14编码范例11-10使用锁定操作的示例11-17编码范例11-11令I/O操作和错误检查独立化11-18编码范例11-12销毁共享对象11-19编码范例11-13以多线程安全方式使用iostream对象11-20编码范例14-1string提取运算符14-7编码范例A-1预处理程序示例程序foo.
ccA-12编码范例A-2使用-E选项的foo.
cc的预处理程序输出A-12xxvii开始之前本手册指导您如何使用SunStudio8的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章则提供了关于生成库的信息.
xxviiiC++用户指南2004年4月排版惯例表P-1排版惯例字体含义示例AaBbCc123命令、文件和目录的名称;计算机屏幕输出编辑您的.
login文件.
使用ls-a列出所有文件.
%Youhavemail.
AaBbCc123输入的内容,以便与计算机屏幕输出相区别%suPassword:AaBbCc123书名、新词或术语以及要强调的词请阅读《用户指南》的第6章.
这些称作类选项.
您必须是超级用户才能执行此操作.
AaBbCc123命令行变量;用实际名称或值替换要删除文件,请键入rmfilename.
表P-2代码惯例代码符号含义表示法代码示例[]括号包含可选参数.
O[n]O4,O{}大括号包含所需选项的选项集合.
d{y|n}dy|"pipe"或"bar"符号用于分隔参数,所以只能选择两者之一.
B{dynamic|static}Bstatic:与逗号一样,分号有时可用于分隔参数.
Rdir[:dir]R/local/libs:/U/a.
.
.
省略号表示一系列省略.
xinline=f1[,.
.
.
fn]xinline=alpha,dos开始之前xxixShell提示符访问SunStudio软件和手册页编译器和工具以及它们的手册页并没有安装到标准的和/usr/share/man目录中.
要访问编译器和工具,必须正确设置PATH环境变量(请参阅第xxix页的"访问编译器和工具").
要访问手册页,必须正确设置MANPATH环境变量(请参阅第xxx页的"访问手册页").
关于PATH变量的更多信息,请参阅csh(1)、sh(1)和ksh(1)手册页.
关于MANPATH变量的更多信息,请参阅man(1)手册页.
关于设置PATH变量和MANPATH变量以访问此发行版本的更多信息,请参阅安装指南或询问系统管理员.
注–本节中的信息假设SunStudio编译器和工具安装在/opt目录中.
如果软件没有安装在/opt中,请询问系统管理员以获取系统中的等价路径.
访问编译器和工具使用下列步骤可决定是否需要更改PATH变量以访问编译器和工具.
要决定是否需要设置PATH环境变量1.
通过在命令提示符后输入下列内容以显示PATH变量的当前值.
Shell提示符Cshellmachine-name%Cshell超级用户machine-name#Bourneshell和Kornshell$Bourneshell和Kornshell的超级用户#%echo$PATHxxxC++用户指南2004年4月2.
查看输出中是否有包含/opt/SUNWspro/bin/的路径字符串.
如果找到该路径,您的PATH变量已经设置好,可以访问编译器和工具了.
如果没有找到该路径,按照下一步中的指示可设置PATH环境变量.
要设置PATH环境变量以访问编译器和工具1.
如果使用的是Cshell,请编辑起始.
cshrc文件.
如果使用的是Bourneshell或Kornshell,请编辑起始.
profile文件.
2.
将下列内容增加到PATH环境变量.
如果已安装SunONEStudio软件或ForteDeveloper软件,则将以下路径增加到这些安装的路径之前.
/opt/SUNWspro/bin访问手册页使用下列步骤可决定是否需要更改MANPATH变量以访问手册页.
要决定是否需要设置MANPATH环境变量1.
通过在命令提示符后输入下列内容以请求dbx手册页.
2.
如果有输出的话,请查看输出.
如果dbx(1)手册页无法找到或者显示的手册页不是用于安装软件的当前版本,请按照下一步中的指示可设置MANPATH环境变量.
要设置MANPATH环境变量以访问手册页1.
如果使用的是Cshell,请编辑起始.
cshrc文件.
如果使用的是Bourneshell或Kornshell,请编辑起始.
profile文件.
2.
将下列内容增加到MANPATH环境变量.
/opt/SUNWspro/man%mandbx开始之前xxxi访问集成开发环境SunStudio8集成开发环境(IDE)提供了创建、编辑、生成、调试和分析C、C++或Fortran应用程序性能的模块.
IDE需要SunStudio8的核心平台组件.
如果核心平台组件没有安装到以下位置之一,则必须将SPRO_NETBEANS_HOME环境变量设置到安装核心平台组件的位置(installation_directory/netbeans/3.
5R).
I缺省安装目录/opt/netbeans/3.
5RI与SunStudio8的编译器和工具组件相同的位置(例如安装在/foo/SUNWspro中的编译器和工具组件和/foo/netbeans/3.
5R中的核心平台组件).
启动IDE的命令是sunstudio.
有关该命令的详细信息,请参阅sunstudio(1)手册页.
访问编译器和工具文档您可以在下列位置访问文档:I可以在随软件一起安装的文档索引file:/opt/SUNWspro/docs/index.
html中(位于本地系统或网络上)获取文档.
如果软件没有安装在/opt中,请询问系统管理员以获取系统中的等价路径.
I大多数的手册都可以从docs.
sun.
comsmweb站点上获得.
下列文档只能在安装的软件中获得:IStandardC++LibraryClassReferenceIStandardC++LibraryUser'sGuideITools.
h++ClassLibraryReferenceITools.
h++User'sGuideI发行版本说明可以从docs.
sun.
comweb站点上获得.
I在IDE中通过[帮助]菜单或窗口和对话框上的[帮助]按钮可以访问IDE所有组件的联机帮助.
您可以通过因特网在docs.
sun.
comweb站点(http://docs.
sun.
com)上阅读、打印和购买SunMicrosystems的各种手册.
如果找不到手册,请参阅和软件一起安装在本地系统或网络中的文档索引.
注–Sun不对本文档所提及的第三方web站点的可用性负责,而且Sun不认可也不对以上站点或资源上的任何内容、广告、产品或其它资料承担责任.
此外,Sun公司也不就因您使用或依靠以上任何站点或资源上的(或通过该站点或资源所获取的)内容、物品或服务所产生的(或所谓产生的)任何损失承担责任.
xxxiiC++用户指南2004年4月使用易读格式的文档该文档以易读格式提供,以方便残障用户使用辅助技术进行阅读.
您还可以按照下表所描述的信息找到文档的易读版本.
如果软件没有安装在/opt中,请询问系统管理员以获取系统中的等价路径.
相关编译器和工具文档下表描述的相关文档可以在file:/opt/SUNWspro/docs/index.
html和http://docs.
sun.
com上获得.
如果软件没有安装在/opt中,请询问系统管理员以获取系统中的等价路径.
文档类型易读版本的格式和位置手册(第三方手册除外)HTML,位于http://docs.
sun.
com第三方手册:StandardC++LibraryClassReferenceStandardC++LibraryUser'sGuideTools.
h++ClassLibraryReferenceTools.
h++User'sGuideHTML,位于安装的软件中的文档索引file:/opt/SUNWspro/docs/index.
html自述文件和手册页HTML,位于安装的软件中的文档索引file:/opt/SUNWspro/docs/index.
html联机帮助通过IDE中的[帮助]菜单可以使用HTML发行说明HTML,位于http://docs.
sun.
com文档标题描述《数值计算指南》描述关于浮点计算数值精确性的问题.
开始之前xxxiii访问相关的Solaris文档下表描述了可从docs.
sun.
comweb站点上获得的相关文档.
访问相关的C++手册页本手册提供了可用于C++库的手册页列表.
下表列出了与C++相关的其它手册页.
文档集合文档标题描述SolarisReferenceManualCollection参阅手册页部分的标题.
提供关于Solaris操作环境的信息.
SolarisSoftwareDeveloperCollectionLinkerandLibrariesGuide描述Solaris链接编辑器和运行时链接程序的操作.
SolarisSoftwareDeveloperCollectionMultithreadedProgrammingGuide涵盖POSIX和Solaris线程API、使用同步对象进行程序设计、编译多线程程序和多线程程序的查找工具.
标题描述c++filt按顺序复制每个文件名,并在解码类似C++还原名称的符号之后将文件名写入标准输出dem还原指定的一个或多个C++名称fbe从汇编语言源文件创建目标文件fpversion打印系统CPU和FPU的相关信息gprof生成程序的可执行配置文件ild增量链接,允许将修改后的目标代码插入到先前生成的可执行文件inline扩展汇编程序的内联过程调用lex生成词法分析程序rpcgen生成C/C++代码以实现RPC协议sigfpe允许对指定SIGFPE代码进行信号处理stdarg处理变量参数列表xxxivC++用户指南2004年4月其它公司出版的书籍以下是部分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).
varargs处理变量参数列表version显示目标文件或二进制文件的版本标识yacc将相关的语法转换成一组表,用于执行LALR(1)分析算法的简单自动化标题描述开始之前xxxv开发人员资源访问http://www.
sun.
com/developers/studio以查找以下经常更新的资源:I关于编程技术和最佳方法的文章I短小编程提示的知识库I编译器和工具组件的文档以及与软件同时安装的文档的更正I支持等级信息I用户论坛I可下载代码示例I新技术预览您可以在http://developers.
sun.
com/上找到开发人员的额外资源.
与Sun技术支持联系如果您有关于本产品的技术问题而本文档未予以解答,请访问:http://www.
sun.
com/service/contacting发送意见Sun致力于提高文档质量,并欢迎您提出宝贵的意见和建议.
请通过电子邮件将您的意见发送至以下地址:docfeedback@sun.
com请在电子邮件的主题行中包含文档的部件号码(817-5808-10).
xxxviC++用户指南2004年4月第I部分C++编译器1-1第1章C++编译器本章简要介绍了C++编译器的有关概念.
1.
1标准的符合性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-2C++用户指南2004年4月1.
2C++自述文件C++编译器的自述文件强调了关于编译器的重要信息,其中包括:I在手册印刷之后发现的信息I新特性和更改的特性I软件更正I问题和解决办法I限制和不兼容I可交付使用的库I未实现的标准要查看C++自述文件的文本格式文件,请在命令提示符后输入以下命令:要访问自述文件的HTML格式文件,请在您的NetscapeCommunicator4.
0或兼容版本的浏览器中打开以下文件:/opt/SUNWspro/docs/index.
html(如果您的C++编译器软件没有安装在/opt目录中,请询问系统管理员以了解系统中的等价路径.
)浏览器可以显示HTML文档的索引.
要打开自述文件,请在索引中查找它的对应条目,然后单击主题.
1.
3手册页联机手册(man)页提供了关于命令、函数、子例程或这些信息集合的直观的文档.
可以通过运行以下命令来显示手册页:在C++文档中显示了手册页参考的主题名称和手册部分编号:例如访问CC(1)时可以使用manCC.
其它部分(例如用ieee_flags(3M)表示的节)要使用man命令和该命令的-s选项来访问:example%CC-xhelp=readmeexample%mantopicexample%man-s3Mieee_flags第1章C++编译器1-31.
4许可C++编译器使用《安装指南》中描述的网络许可.
如果调用了编译器且许可证可用,那么编译器将启动.
一个许可可供一位用户在一台计算机上同时进行任意数量的编译.
运行C++和各种公用程序可能需要多个许可证,这取决于您购买的软件包.
1.
5C++编译器的新特性C++编译器在本发行版本中新增了以下新特性.
1.
5.
1一般增强I不再需要模板缓存:-instances此发行版本C++编译器极大地改善了模板实例化.
使用缺省模板实例化模型的程序现在可以在同一目录下生成多个程序.
以前依赖于可替换的实例化模型(如-instances=static)的大多数程序现在可以使用新的缺省实例化模型.
对模板实例化进行的改进和更改或者由于不再使用模板缓冲而减少了编译时间,或者由于避免了使用重复的静态函数而减小了可执行程序的大小.
详细信息请参阅第17-37页的"-instances=a".
I变量作用域不再需要链接程序mapfile:-xldscope现在可以使用两种不同的方法来控制动态库符号的输出.
这项功能称为链接程序作用域,链接程序mapfile早就对它提供了支持.
首先,可以在代码中嵌入新的声明说明符.
只要在代码中直接添加__global、__symbolic、和__hidden,就可以不必使用mapfile.
其次,可以通过在命令行指定-xldscope来覆盖变量作用域的缺省设置.
请参阅第17-94页的"-xldscope={v}".
关于声明说明符的详细信息,请参阅第4-2页的"链接程序作用域".
I新的并且功能强大的宏诊断工具:-xdumpmacros此发行版本新引入了两个pragma和一个编译器选项可帮助您跟踪应用程序中的宏.
其中包括定义在系统头文件中的宏.
1-4C++用户指南2004年4月可以在命令行使用-xdumpmacros选项来查看宏定义,也可以查看宏的定义位置、宏的取消定义位置以及宏在程序中的使用位置.
如果要缩小范围,可以在源码中直接使用dumpmacros和end_dumpmacros这两个新pragma.
请参阅第17-81页的"-xdumpmacros[=value[,value.
.
.
]]"、第18-5页的"#pragmadumpmacros"和第18-6页的"#pragmaend_dumpmacros".
I支持VIS[tm]开发者工具包:-xvis(SPARC)在使用VIS指令集软件开发者工具包(VSDK)中定义的汇编语言模板时,可以使用-xvis=[yes|no]选项.
缺省为-xvis=no.
VIS指令集是SPARCv9指令集的扩展.
尽管UltraSPARC是64位处理器,但在很多情况下数据都限制在8位或16位范围内,特别是多媒体应用程序中.
VIS指令可以用一条指令处理4个16位数据,这个特性使得处理诸如图像、线性代数、信号处理、音频、视频以及网络等新媒体的应用程序的性能大大提高.
有关VSDK的更多信息,请参阅http://www.
sun.
com/processors/vis.
请参阅第17-139页的"-xvis[={yes|no}]".
I支持C99运行时库和环境:-xlang=c99在支持C99标准(ISO/IEC9899:1999,编程语言-C)的操作系统上,-xlang=c99能够为调用C库函数的C和C++代码指定C99运行时行为特性.
某些C99行为特性,例如C复数类型,要求C编译器和-xc99=%all选项一起使用,而某些行为特性,例如printf,就没有这样的限制.
注–兼容模式(-compat=4)不支持C99.
请参阅第17-93页的"-xlang=language[,language]".
I支持UTF-16字符串文字:-xustr如果需要支持使用ISO10646UTF-16字符串文字的国际化程序,那么就要指定-xustr=ascii_utf16_ushort选项.
也就是说,如果您的代码包含16位字符组成的字符串文字,那么就需要使用该选项.
如果不指定该选项,编译器既不生成、也不识别16位的字符串文字.
该选项使U"ASCII_string"字符串文字处理成无符号短整数的数组.
因为这样的字符串还不属于任何标准,所以该选项的作用是使非标准C++得以识别.
请参阅第17-138页的"-xustr={ascii_utf16_ushort|no}".
I为OpenMP提供的扩展支持:-xopenmpC++编译器为显式并行的OpenMP接口继续提供支持.
编译器对OpenMP功能进行了扩展,增加了以下功能:I允许在OpenMP数据子句中包含类对象.
I允许在类成员函数中出现OpenMPpragma.
关于OpenMP编译器命令的更多信息,请参阅第17-109页的"-xopenmp[=i]".
关于生成多进程应用程序的OpenMPC++应用程序编程接口(API)的更多信息,请参阅《OpenMPAPI用户指南》.
第1章C++编译器1-5I改进-xprofile(SPARC)-xprofile选项提供以下改进功能:I支持文件配置共享库I使用-xprofile=collect-mt选项的线程安全的配置文件集合I对在单个配置文件目录下文件配置多程序的支持有所改进.
通过设置-xprofile=use选项,编译器能够在配置目录下为多个拥有不同基名的目标文件找到配置数据.
在找不到目标文件的配置文件数据的情况下,编译器会使用新的选项:-xprofile_pathmap=collect-prefix:use-prefix.
请参阅第17-123页的"-xprofile=p"和第17-125页的"-xprofile_pathmap".
1.
5.
2更快的编译:I加速语法检查:-xe当指定-xe时,编译器只检查语法和文法错误,并且不生成任何目标代码.
如果不需要编译器生成目标文件,就可以使用-xe选项.
例如,如果要使用删除代码的方法来确定导致错误消息的原因,使用-xe可以加速编辑、编译周期.
请参阅第17-85页的"-xe".
I更快速的文件配置:-xprofile_ircache在use阶段,同时使用-xprofile_ircache[=path]和-xprofile=collect|use会重用收集阶段保存的编译数据,从而可以减少编译时间.
在编译大程序时,由于中间数据的保存,使得使用阶段的编译时间大大减少.
注意,所保存的数据会占用相当大的磁盘空间.
请参阅第17-125页的"-xprofile_ircache[=path]".
I不再使用冗余的模板实例化:-instlib=filename使用-instlib=filename选项可以避免在函数库和当前对象中生成重复的模板实例化.
一般来说,如果程序与函数库共享大量的实例,则可以试试-instlib=filename选项,您会发现编译时间会减少.
请参阅第17-38页的"-instlib=filename".
I使用-template=geninlinefuncs生成函数一般情况下,C++编译器不会生成内联模板函数,除非该函数既被调用了,又不能内联.
然而,如果指定-template=geninlinefuncs,编译器会将以前未生成的显式实例化类模板的内联成员函数实例化.
两种情况下,对这些函数的链接都是局部的.

请参阅第17-59页的"-template=opt[,opt.
.
.
]".
1-6C++用户指南2004年4月I预编译头文件:-xpch本发行版本的编译器新增了预编译头文件的特性.
预编译头文件的作用是减少源代码共享同一组包含文件的应用程序的编译时间,而且这些包含文件往往有大量的源代码.
预编译头文件的工作机理是,首先从一个源文件收集一组头文件信息,然后在重新编译该源文件或者其它有同样头文件的源文件时就可以使用这些收集到的信息.
要使用这个特性,需要指定-xpch和-xpchstop选项,并同时使用#pragmahdrstop指令.
请参阅第17-112页的"-xpch=v"、第17-115页的"-xpchstop=file"和第18-7页的"#pragmahdrstop".
I通过-xjobs=n使用多个处理器(SPARC)指定-xjobs=n选项用来设定编译器生成多少个进程来完成它的任务.
在多cpu机器上,该选项可以减少生成时间.
目前,-xjobs只在与-xipo一起使用时才有效.
如果指定-xjobs=n,过程间调用优化器在编译不同的文件时会用n作为它能启动的代码生成器实例的最大数.
请参阅第17-92页的"-xjobs=n".
1.
5.
3更便捷的移植I使用-xmemalign简化移植使用-xmemalign选项用来控制编译器对数据对齐的假设.
通过控制可能会出现非对齐内存访问的代码和出现非对齐内存访问时的处理程序,可以更轻松的将程序移植到Solaris操作环境.
请参阅第17-101页的"-xmemalign=ab".
I使用-xchar设置字符的符号有些系统将字符类型定义成无符号类型,-xchar[={signed|s|unsigned|u}]选项使得易于迁移这些系统上的程序.
如果不是从这样的系统中迁移,最好不要使用该选项.
只有那些依赖字符类型符号的程序才需要重写,它们要改写成显式指定有符号或者无符号.
请参阅第17-74页的"-xchar[=o]".
I使用-xport64调试移植代码使用新的-xport64选项来帮助将代码移植到64位环境.
具体来说,该选项会对以下情况提示警告信息:值的截断(包括指针),符号扩展以及对位压缩的更改.
将代码从诸如V7(ILP32)的32位体系结构移植到诸如V9(LP64)的64位体系结构时,这些更改是很通常的.
请参阅第17-116页的"-xport64[=(v)]".
第1章C++编译器1-71.
5.
4改进的性能I使用支持数据线程局部存储的链接程序,可以改善运行时的性能:-xthreadvar(SPARC)可以使用编译器新增的链接程序支持的线程局部存储特性来完成以下功能:I快速实现POSIX接口中的分配线程数据.
I将多进程程序转换成多线程程序.
I将使用线程局部存储的Windows应用程序移植到Solaris操作环境.
I快速实现OpenMP中的线程私有变量.
通过声明线程局部变量,编译器现在可以支持线程局部存储.
这个声明包括一个普通的变量声明和额外的__thread变量说明符,另外还需要在命令行加上-xthreadvar选项.
请参阅第17-135页的"-xthreadvar[=o]".
关于声明说明符的详细信息,请参阅第4-3页的"线程局部存储".
I通过减少缺页以减少运行时间:-xF使用-xF新特性可以使链接程序对变量和函数进行重组以达到最优.
这有助于解决以下会对运行时性能产生负面影响的问题:I在内存中存放位置很近的无关变量会造成缓存和页的竞争.
I在内存中存放位置很远的相关变量会造成过大的工作集.
I未用到的弱变量副本会造成过大的工作集,从而降低有效数据密度.
请参阅第17-85页的"-xF[=v[,v.
.
.
]]".
I使用新的pragma命令减少运行时间C++编译器目前支持四个新的pragma命令,它们可以改进代码的优化:I第18-4页的"#pragmadoes_not_read_global_data"I第18-4页的"#pragmadoes_not_return"I第18-5页的"#pragmadoes_not_write_global_data"I第18-10页的"#pragmararely_called"请参阅第18-1页的"Pragma".
I使用链接时优化器减少运行时间:-xlinkopt当指定-xlinkopt命令时,C++编译器可以对可重定位目标文件进行链接时优化.
指定-xlinkopt选项时,编译器会在链接时进行一些额外的优化,并且不会修改所链接的.
o文件.
这些优化仅仅在可执行程序中才出现.
当编译整个程序并且使用配置文件反馈时,-xlinkopt选项才最有效.
请参阅第17-98页的"-xlinkopt[=level]".
1-8C++用户指南2004年4月I使用-xpagesize=n(SPARC)减少运行时间使用-xpagesize=n选项来设置想要的堆栈和堆的页面大小.
n可以是8K、64K、512K、4M、32M、256M、2G、16G或缺省.
您必须在目标平台上为Solaris操作环境指定正确的页面大小,其值由getpagesize(3C)返回.
如果不指定有效的页面大小,运行时该请求就会被忽视.
您可以使用pmap(1)或meminfo(2)来决定目标平台的页面大小.
注–该功能只在Solaris9操作环境中可用.
使用此选项编译的程序不能链接到早期的Solaris操作环境中.
该选项其实是代表-xpagesize_stack和-xpagesize_heap的宏.
请参阅第17-110页的"-xpagesize=n"、第17-111页的"-xpagesize_heap=n"和第17-111页的"-xpagesize_stack=n".
1.
5.
5增加的警告和错误控制I使用-erroff过滤警告消息使用新的-erroff选项可以禁止编译器前端输出警告消息.
注意,错误消息和驱动程序输出的消息都不会受到影响.
也可以使用-erroff挑选出特定的警告消息,以便只有它被禁止,或者只有它可以输出.
例如,-erroff=tag会禁止tag指定的警告消息.
另一方面,-erroff=%all,no%tag会禁止除tag指定的消息之外的所有警告消息.
使用-errtags=yes选项可以显示警告消息的标记.
请参阅第17-13页的"-erroff[=t]".
I使用-errtags和-errwarn终止编译过程使用-errtags和-errwarn选项可以使编译器在输出某条特定警告后终止.
首先指定-errtags=yes来获取该特定警告的标记,然后指定-errwarn=tag,其中tag是-errtags为该警告消息返回的唯一标识符.
也可以通过指定-errwarn=%all使编译器输出任何警告时都终止编译过程.
请参阅第17-14页的"-errtags[=a]"和第17-15页的"-errwarn[=t]".
I使用-filt=[no%]stdlib选项改进标准库名的过滤功能:缺省情况下,将设置-filt=[no%]stdlib选项,用来简化链接程序和编译器输出的错误消息中来自标准库的名称.
这能帮助您更容易识别出标准库函数名.
指定-filt=no%stdlib会关掉过滤功能.
请参阅第17-22页的"-filt[=filter[,filter.
.
.
]]".
第1章C++编译器1-91.
6C++公用程序以下C++公用程序现已并入传统的UNIX工具并且与UNIX操作系统捆绑在了一起:Ilex生成文本简单词法分析的程序Iyacc根据语法生成C函数分析输入流Iprof生成程序模块的执行配置文件Igprof按过程来配置程序运行时性能Itcov按语句来配置程序运行时性能关于这些UNIX工具的更多信息,请参阅《程序性能分析工具》和相关的手册页.
1.
7本地语言支持此发行版本的C++支持使用英语以外的其它语言进行应用程序的开发,包括了大多数欧洲语言和日语.
因此,您可以十分便捷地将应用程序从一种语言切换到另一种语言.
此功能被称为国际化.
通常,C++编译器按如下方式实现国际化:IC++从国际化的键盘识别ASCII字符(也就是说,它具有键盘独立性和8位清除).
IC++允许使用本地语言打印某些消息.
IC++允许在注释、字符串和数据中使用本地语言.
IC++只支持与扩展UNIX字符(EUC)兼容的字符集,在该字符集中,字符串中的每个空字节代表空字符,字符串中每个具有"/"字符的ascii值的字节代表"/"字符.
变量名称不能国际化,必须使用英文字符集.
您可以设置语言环境将应用程序从一种本地语言更改为另一种语言.
关于这一点和其它本地语言支持功能的信息,请参阅操作环境文档.
1-10C++用户指南2004年4月2-1第2章使用C++编译器本章描述了如何使用C++编译器.
任何编译器的主要用途是将高级语言(如C++)编写的程序转换成目标计算机硬件可执行的数据文件.
您可以使用C++编译器完成以下任务:I将源文件转换成可重定位的二进制(.
o)文件、静态(归档)库(.
a)文件(使用-xar)或动态(共享)库(.
so)文件.
其中二进制文件可以在以后链接成可执行文件.
I将目标文件或库文件(或两者)链接或重链接成可执行文件I启用运行时调试(-g)来编译可执行文件I启用运行时语句或过程级别的文件配置(-pg)来编译可执行文件2.
1入门本节简要概述了如何使用C++编译器编译和运行C++程序.
关于命令行选项的完整参考,请参阅附录17.
注–本章中的命令行示例说明了CC的用法.
打印输出可能会稍有不同.
生成和运行C++程序的基本步骤包括:1.
使用编辑器创建具有表2-1中列出的有效后缀之一的C++源文件2.
调用编译器来生成可执行文件3.
通过输入可执行文件的名称来启动程序2-2C++用户指南2004年4月以下程序在屏幕上显示消息:在此示例中,CC编译源文件greetings.
cc,并且在缺省情况下将编译可执行程序生成a.
out文件.
要调用该程序,可在命令行提示符后输入可执行文件的名称a.
out.
按传统方法,UNIX编译器为可执行文件a.
out命名.
每次编译都写入到同一个文件是比较笨拙的方法.
另外,如果已经有这样一个文件存在,下次运行编译器时该文件将被覆盖.
如以下示例所示,改为使用-o编译器选项来指定可执行输出文件的名称:在此示例中,-o选项告知编译器将可执行代码写入文件greetings.
(对于只有一个源文件的程序,通常是命名为不带后缀的源文件名称.
)或者,可以在每次编译以后使用mv命令来重命名缺省的a.
out文件.
无论是哪种方式,都可以输入可执行文件的名称来运行程序: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章使用C++编译器2-112.
5.
3预定义的名称附录中的表Q-3显示了预定义的宏.
您可以在#ifdef这样的预处理程序条件中使用这些值.
+p选项防止了sun、unix、sparc和i386预定义宏的自动定义.
2.
5.
4#error在发出警告以后,#error指令不会继续编译.
指令原来的行为是发出警告并继续编译.
其新行为(和其它编译器保持一致)是发出错误消息并立即停止编译.
编译器退出并报告失败.
2.
6内存要求编译需要的内存量取决于多个参数,包括:I每个过程的大小I优化级别I为虚拟内存设置的限制I磁盘交换文件的大小在SPARC平台上,如果优化器用完了所有内存,那么它将通过在较低优化级别上重试当前过程来尝试恢复.
然后优化器将在命令行用-xOlevel选项指定的原优化级别上,继续随后的例程.
如果编译包括大量例程的单独源文件,编译器可能会用完所有内存或交换空间.
如果编译器用完了内存,可以尝试降低优化级别.
或者,可以将多例程的源文件分割为单例程的文件.
2.
6.
1交换空间大小swap-s命令显示了可用的交换空间.
更多信息请参阅swap(1M)手册页.
以下示例显示了swap命令的使用:example%swap-stotal:40236kbytesallocated+7280kreserved=47516kused,1058708kavailable2-12C++用户指南2004年4月2.
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-d16000第2章使用C++编译器2-13在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.
C2-14C++用户指南2004年4月2.
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.
cc第2章使用C++编译器2-15将以下各行增加到makefile.
缩进的行必须以制表符开头.
2.
7.
3.
3和标准库头文件一起使用make标准库文件的名称不带.
h后缀,而是被命名为istream、fstream等等.
而且模板源文件被命名为istream.
cc、fstream.
cc等等.
如果在Solaris2.
6操作环境或Solaris7操作环境中,将一个标准库头文件(如)包括在程序中,并且makefile具有.
KEEP_STATE,那么您可能会遇到问题.
例如,如果您将包括到程序中,make公用程序会认为istream是一个可执行文件并使用缺省规则由istream.
cc生成istream,这将会产生令人误解的错误消息.
(istream和istream.
cc都安装在C++包括文件目录中.
)一种解决方法是在串行模式下使用dmake(dmake-mserial)而不使用make公用程序.
另一种更直接的方法是使用make带-r选项.
-r选项禁用了缺省的make规则.
这个解决方法有时会终止生成过程.
第三种解决方案是不使用.
KEEP_STATE目标.
.
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$%$);.
.
.
};4-8C++用户指南2004年4月4.
10使用函数名称的预定义__func__符号使用-features=extensions时,编译器将每个函数中的标识符__func__隐式声明为constchar的静态数组.
如果程序使用标识符,那么编译器也在function-name是函数原始名称的位置提供以下定义.
类成员关系、名称空间和重载不反映在名称中.

例如,请考虑以下代码段.
每次调用函数时,函数将把以下内容打印到标准输出流.
staticconstchar__func__[]="function-name";#includevoidmyfunc(void){printf("%s\n",__func__);}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代码.
该宏最适用于从非原型函数定义中区分原型函数定义.
#ifdef__STDC__intfunction(char*C++&ANSIC声明#elseintfunction();//K&RC#endif5-2C++用户指南2004年4月宏__cplusplus不在C中定义,但在C++中定义.
注–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"{#endifntg1();ntg2();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-4C++用户指南2004年4月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.
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-2C++用户指南2004年4月6.
1.
2函数模板定义声明模板后,您还必须定义该模板.
定义提供了实现模板的足够信息.
以下示例定义了在前一个示例中声明的模板.
模板定义通常出现在头文件中,所以可能会在多个编译单元中重复.
不过所有的定义都必须是相同的.
这种约束称为单次定义规则.
编译器不支持函数参数列表中非类型模板参数的表达式,如以下示例所示.

6.
1.
3函数模板用法声明后,模板可以像其它函数一样使用.
模板的使用由命名模板和提供函数参数组成.

编译器可以从函数参数类型推断出模板类型参数.
例如,您可以使用上面声明的模板,具体步骤如下所示.
如果模板参数不能从函数参数类型推断出,则调用函数时必须提供模板参数.
例如:templateNumbertwice(Numberoriginal){returnoriginal+original;}//不支持包含函数参数列表中//非类型模板参数的表达式templatevoidfoo(mytypetemplatevoidfoo(inta[I+J]doubletwicedouble(doubleitem){returntwice(item);}templateTfunc();//无函数参数intk=func();//显式提供模板参数第6章创建和使用模板6-36.
2类模板类模板描述了一组相关的类或数据类型,它们仅通过类型、整数值、具有全局链接的指针变量(或引用)或它们的组合来区分.
类模板尤其适用于描述通用但类型安全的数据结构.
6.
2.
1类模板声明类模板声明仅提供了类的名称和类的模板参数.
这种声明是不完整的类模板.

以下示例是命名为Array类的模板声明,该类可以将任何类型作为参数.
该模板是命名为String类的模板,该类将unsignedint作为参数.
6.
2.
2类模板定义类模板定义必须声明类数据和函数成员,如以下示例所示.
templateclassArray;templateclassString;templateclassArray{Elem*data;intsize;public:Array(intsz);intGetSize();Elem&operator[](intidx);};6-4C++用户指南2004年4月与函数模板不同,类模板可以同时具有类型参数(例如classElem)和表达式参数(例如unsignedSize).
表达式参数可以是:I具有整数类型或枚举的值I指向对象的指针或到对象的引用I指向函数的指针或到函数的引用I指向类成员函数的指针6.
2.
3类模板成员定义类模板的完整定义需要类模板函数成员和静态数据成员的定义.
动态(非静态)数据成员由类模板声明完全定义.
6.
2.
3.
1函数成员定义模板函数成员的定义由模板参数规范及后跟函数定义组成.
函数标识符通过类模板的类名称和模板参数来限定.
以下示例说明了Array类模板的两个函数成员的定义,该模板具有template的模板参数规范.
每个函数标识符都通过模板类名称和模板参数Array来限定.
templateclassString{chardata[Size];staticintoverflows;public:String(char*initial);intlength();};templateArray::Array(intsz){size=sz;data=newElem[size];}templateintArray::GetSize(){returnsize;}第6章创建和使用模板6-5该示例说明了String类模板的函数成员定义.
6.
2.
3.
2静态数据成员定义模板静态数据成员的定义由后跟变量定义的模板参数规范组成,在此处变量标识符通过类模板名称和类模板实际参数来限定.
6.
2.
4类模板的用法模板类可以在使用类型的任何地方使用.
指定模板类包括了提供模板名称和参数的值.

以下示例中的声明创建了基于Array模板的int_array变量.
变量的类声明和方法集与Array模板中的类声明和方法集相同,不同之处是Elem替换为int(请参阅第6-6页的第6.
3节"模板实例化").
本示例中的声明使用String模板创建short_string变量.
需要任何其它成员函数时,您可以使用模板类成员函数.
#includetemplateintString::length(){intlen=0;while(lenString::String(char*initial){strncpy(data,initial,Size);if(length()==Size)overflows++;}templateintString::overflows=0;Arrayint_array(100);Stringshort_string("hello");intx=int_array.
GetSize();intx=short_string.
length();6-6C++用户指南2004年4月6.
3模板实例化模板实例化包含了为模板参数的特定组合生成固定类或函数(实例).
例如,编译器生成了Array的类和Array的不同类.
通过替换模板类定义中模板参数的模板参数,可以定义这些新的类.
在上一节"类模板"所述的Array示例中,编译器在Elem出现的位置替换int.
6.
3.
1隐式模板实例化使用模板函数或模板类时需要实例.
如果这种实例还不存在,则编译器隐式实例化模板参数组合的模板.
6.
3.
2显式模板实例化编译器仅为实际使用的那些模板参数组合而隐式实例化模板.
该方法不适用于构造提供模板的库.
C++提供了显式实例化模板的功能,如以下示例所示.
6.
3.
2.
1模板函数的显式实例化要显式实例化模板函数,请在template关键字后跟函数的声明(无定义);而要实例化函数标识符,则请后跟模板参数.
在编译器可以推断出模板参数时,模板参数可以省略.
templatefloattwice(floatoriginal);templateinttwice(intoriginal);第6章创建和使用模板6-76.
3.
2.
2模板类的显式实例化要显式实例化模板类,请在template关键字后跟类的声明(无定义);而要实例化类标识符,请后跟模板参数.
显式实例化类时,所有的类成员也必须实例化.
6.
3.
2.
3模板类函数成员的显式实例化要显式实例化模板类函数成员,请在template关键字后跟函数的声明(无定义);而要实例化由模板类限定的函数标识符,则请后跟模板参数.
6.
3.
2.
4模板类静态数据成员的显式实例要显式实例化模板类静态数据成员,请在template关键字后跟成员的声明(无定义);而要实例化由模板类限定的成员标识符,则请后跟模板参数.
templateclassArray;templateclassString;templateintArray::GetSize();templateintString::length();templateintString::overflows;6-8C++用户指南2004年4月6.
4模板组合可以用嵌套方式使用模板.
这种方式尤其适用于在通用数据结构上定义通用函数,与在标准C++库中相同.
例如,模板排序函数可以在模板数组类上声明:并定义为:上述示例定义了预先声明的Array类模板对象上的排序函数.
下一个示例说明了排序函数的实际用法.
6.
5缺省模板参数您可以将缺省值赋予类模板(但不是函数模板)的模板参数.
如果模板参数具有缺省值,则该参数后的所有参数也必须具有缺省值.
模板参数仅能具有一个缺省值.
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);//排序该数组templateclassArray;templateclassString;第6章创建和使用模板6-96.
6模板专用化将模板参数的某些组合视为特殊的参数可以优化性能,如以下twice的示例所示.
或者,模板描述将无法处理一组可能的参数,如以下sort的示例所示.
模板专用化允许您定义实际模板参数给定组合的可选实现.
模板专用化覆盖了缺省实例化.

6.
6.
1模板专用化声明使用模板参数的组合之前,您必须声明专用化.
以下示例声明了twice和sort的专用实现.
如果编译器可以明确决定模板参数,则您可以省略模板参数.
例如:6.
6.
2模板专用化定义必须定义声明的所有模板专用化.
下例定义了上一节中声明的函数.
templateunsignedtwice(unsignedoriginal);templatesort(Arraystore);templateunsignedtwice(unsignedoriginal);templatesort(Arraystore);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示例3第6章创建和使用模板6-116.
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-12C++用户指南2004年4月6.
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章创建和使用模板6-136.
7.
3模板函数的友元声明模板在使用之前必须先声明.
模板的使用由友元声明构成,不是由模板的声明构成.
实际的模板声明必须在友元声明之前.
例如,编译系统尝试链接以下示例中生成的目标文件时,会生成未实例化operatortemplateclassarray{intsize;public:array();friendstd::ostream&operator&);};#endifarray.
cc#include#includetemplatearray::array(){size=1024;}templatestd::ostream&operator&rhs){returnoutrhs.
sizemain.
cc#include#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&);};#endif第6章创建和使用模板6-156.
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-16C++用户指南2004年4月正确的语法为:6.
7.
6引用静态变量和静态函数在模板定义中,编译器不支持引用在全局作用域或名称空间中声明为静态的对象或函数.
如果生成了多个实例,则每个示例引用到了不同的对象,因此违背了单次定义规则(C++标准的3.
2节).
通常的失败指示是链接时丢失符号.
如果想要所有模板实例化共享单一对象,那么请使对象成为已命名空间的非静态成员.

如果想要模板类的每个实例化不同对象,那么请使对象成为模板类的静态成员.
如果想要模板函数每个实例化的不同对象,那么请使对象具有函数局部化属性.

6.
7.
7在同一目录中使用模板生成多个程序如果要使用模板生成多个程序,那么建议在不同的目录中生成这些程序.
如果要在同一目录中生成多个程序,那么您需要清除不同生成程序之间的系统信息库.
这样可以避免出现任何意外的错误.
更多信息请参阅"共享模板系统信息库"在7-7页.
考虑具有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*.
oab第6章创建和使用模板6-17.
.
.
x.
h.
.
.
templateclassX{public:intopen();intcreate();staticintvariable;};.
.
.
x.
cc.
.
.
templateintX::create(){returnvariable;}templateintX::open(){returnvariable;}templateintX::variable=1;.
.
.
a.
cc.
.
.
#include"x.
h"main(){Xtemp1;temp1.
open();temp1.
create();}6-18C++用户指南2004年4月如果同时生成了a和b,那么在两个生成之间增加makeclean.
以下命令会引起错误:以下命令不会产生任何错误:.
.
.
b.
cc.
.
.
#include"x.
h"main(){Xtemp1;temp1.
create();}example%makeaexample%makebexample%makeaexample%makecleanexample%makeb7-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-2C++用户指南2004年4月7.
2.
2整个类实例化编译器通常实例化独立于其它成员的模板类成员,因此编译器仅实例化程序中使用的成员.
仅用于调试器的方法会因此而不正常地实例化.
有两种方法确保调试成员可用于调试器.
I首先,编写使用模板类实例成员(否则无用)的非模板函数,不需要调用该函数.
I其次,使用-template=wholeclass编译器选项,通知编译器实例化模板类的所有非模板非内联成员,前提是任何这些相同成员都是可实例化的.
ISOC++标准允许开发人员编写模板类,对于这些模板类,可能并不是所有成员都可以使用给定的模板参数.
只要非法成员未被实例化,程序就仍然完好.
ISOC++标准库使用了这种技术.
不过,-template=wholeclass选项实例化所有成员,因此在使用有问题的模板参数来进行实例化时就不能使用这种模板类.
7.
2.
3编译时实例化实例化是C++编译器从模板创建可用的函数或对象的过程.
C++编译器使用了编译时实例化,在编译对模板的引用时强制进行实例化.
编译时实例化的优点是:I调试更为容易错误消息出现在上下文中,同时允许编译器完整回溯到引用点.
I模板实例化始终保持最新.
I包括链接阶段在内的总编译时间减少了.
如果源文件位于不同的目录或您使用了具有模板符号的库,则模板可以多次实例化.

7.
2.
4模板实例的放置和链接从SunC++编译器的5.
5版本开始,实例进入了特殊的地址区,并且链接程序标识并丢弃重复实例.
您可以指示编译器使用五个实例放置和链接方法之一:外部、静态、全局、显式和半显式.
I外部实例适用于大多数程序的开发,并且满足以下条件时可以达到最好的执行效率:I程序中的实例集比较小,但是每个编译单元引用了实例较大的子集.
I很少有在多于一个或两个编译单元中引用的实例.
I静态,废弃见下文.
I缺省的全局实例适用于所有程序的开发,并且当对象引用不同的实例时执行效率可以达到最好.
第7章编译模板7-3I显式实例适用于某些需精确控制的应用程序编译环境.
I半显式实例需要对编译环境的控制程度稍低,但会生成较大的目标文件,并在使用上有限制.
本节讨论了五种实例放置和链接方法.
关于生成实例的更多信息,请参阅第6-6页的第6.
3节"模板实例化".
7.
3外部实例对于外部实例方法,所有实例都放置在模板系统信息库中.
编译器确保只有一个一致的模板实例存在;这些实例既不是未定义的也不是多重定义的.
模板仅在需要时才重新实例化.
对于非调试代码,使用-instances=extern时的所有目标文件(包括模板缓存内的目标文件)的总计大小小于使用-instances=global时的大小.
模板实例接收系统信息库中的全局链接.
使用外部链接时将从当前编译单元引用实例.

注–如果以不同的步骤编译和链接并为编译步骤指定了-instance=extern,则也必须为链接步骤指定-instance=extern.
这种方法的不足之处是缓存会损坏,而且更改程序或程序发生重大更改时必须清除.
缓存是并行编译的瓶颈,因为使用dmake时每次只能有一个编译访问缓存.
另外,每个目录内仅能生成一个程序.
决定缓存中是否存在有效的模板实例比直接在主目标文件中创建实例(如果需要,用完后可以丢弃)要花费更长的时间.
使用instances=extern选项指定外部链接.
因为实例存储在模板系统信息库中,所以您必须使用CC命令将使用外部实例的C++对象链接到程序中.
如果要创建包含所有模板实例的库,则使用具有-xar选项的CC命令.
不要使用ar命令.
例如:更多信息请参阅第16章.
example%CC-xar-instances=extern-olibmain.
aa.
ob.
oc.
o7-4C++用户指南2004年4月7.
3.
0.
1可能的缓存冲突指定-instance=extern时,请勿允许在同一目录中运行不同的编译器版本,以避免可能的缓存冲突.
使用-instances=extern模板模型时,请考虑以下问题:I请勿在同一目录中创建不相关的二进制文件.
在目录中创建任何二进制文件(.
o、.
a、.
so,可执行程序)都应该是相关的,在所有对象、函数的名称中,将公共区输入到两个或多个具有相同定义的目标文件.
I在同一目录中同时运行多个编译是安全的,例如使用dmake时.
与另外一个链接步骤同时运行任何编译或链接步骤是不安全的.
"链接步骤"意味着创建库或可执行程序的任何操作.
确保makefile中的依存关系不允许任何内容与链接步骤以并行方式运行.
7.
3.
1静态实例注–-instances=static选项已废弃.
没有任何理由再使用-instances=static,因为-instances=global现在向您提供了所有静态的优点而没有它的缺点.
以前编译器中提供的该选项用于克服C++5.
5中不存在的问题.
对于静态实例方法,所有实例都被放置在当前编译单元内.
因此,模板在每个重新编译期间重新实例化;这些实例不保存到模板系统信息库.
这种方法的优点是有助于调试,即通过确保从编译单元调用的实例与编译单元一起编译,如此成为可调试的实例.
对于-instances=global,您不能得到该保障.
这种方法的缺点是不遵循语言语义,并且会生成很大的对象和可执行文件.

实例接收静态链接.
这些实例在当前编译单元外部是不可视的或不可用的.
因此,模板可以在多个目标文件中具有相同的实例化.
因为多重实例产生了不必要的大程序,所以对于不可能多重实例化模板的小程序可以使用静态链接.
静态实例的编译速度很快,因此这种方法也适用于"修改并继续"方式的调试.
(请参阅《使用dbx调试程序》.
)注–如果您的程序取决于多个编译单元间的共享模板实例(例如模板类或模板函数的静态数据成员),请勿使用静态实例方法.
否则程序会工作不正常.
使用-instances=static编译器选项指定静态实例链接.
第7章编译模板7-57.
3.
2全局实例与以前的编译器发行版本不同,本版本的编译器无需保护全局实例的多个副本.

这种方法的优点是通常由其它编译器接受的不正确源代码也能在这种模式中接受.
特别的是,从模板实例内对静态变量的引用是不合法的,但通常是可以接受的.

这种方法的缺点是单个目标文件会很大,原因是多个文件中模板实例有多个副本.
如果您使用-g选项(或没有该选项)编译调试的某些目标文件,那么很难预测是否可以获得链接到程序中模板实例的调试或非调试版本.
模板实例接收全局链接.
这些实例在当前编译单元外部是可视的和可用的.

使用-instances=global选项(缺省选项)指定全局实例.
7.
3.
3显式实例在显式实例方法中,仅为显式实例化的模板生成实例.
隐式实例化不能满足该要求.
实例被放置在当前编译单元内.
因此,模板在每个重新编译期间重新实例化,这些模板不保存到模板系统信息库.
这种方法的优点是无需确保曾经只有一个显式实例生成.
并且具有最少量的模板编译和最小的对象大小.
缺点是您必须手动执行所有的实例化.
模板实例接收全局链接.
这些实例在当前编译单元外部是可视的和可用的.
链接程序识别并丢弃重复项目.
使用-instances=explicit选项指定显式实例.
7.
3.
4半显式实例使用半显式实例方法时,仅为显式实例化或模板体内隐式实例化的模板生成实例.
需要显式创建实例的实例是自动生成的,但需给出内部(静态)链接.
主线代码中隐式实例化不满足该要求.
实例被放置在当前编译单元内.
因此,模板在每个重新编译期间重新实例化,这些模板不保存到模板系统信息库.
实例接收全局链接.
这些实例在当前编译单元外部是可视的和可用的.
链接程序识别并丢弃重复项目.
使用-instances=semiexplicit选项指定半显式实例.
7-6C++用户指南2004年4月7.
4模板系统信息库模板系统信息库存储了多个独立编译之间的模板实例,因此模板实例仅当需要时才编译.

模板系统信息库包含了使用外部实例方法时模板实例化所需的所有非源文件.
系统信息库不用于其它种类的实例.
7.
4.
1系统信息库结构缺省情况下,模板系统信息库包含在名为SunWS_cache的缓存目录中.
缓存目录包含在放置目标文件的目录中.
您可以通过设置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.
example%CC-osub/a.
oa.
ccexample%CCsub1/a.
osub2/b.
o第7章编译模板7-77.
4.
4共享模板系统信息库系统信息库内的模板不能违反ISOC++标准的单次定义规则.
也就是说,使用所有的模板时模板必须具有相同的源.
违反该规则会产生意外的行为.
确保不违反该规则的最简单和最保守的方法是在任何一个目录内仅生成一个程序或库.

两个不相关的程序可以使用相同类型的名称或外部名称来表示不同的内容.
如果程序共享模板系统信息库,则模板定义会出现冲突,会产生意外的结果.
7.
4.
5模板实例自动与-instance=extern一致模板系统信息库确保了指定-instances=extern时,系统信息库中的实例状态与源文件保持一致并为最新.
例如,如果源文件用-g选项(即打开调试)编译,则从数据库所需的文件也用-g编译.
此外,模板系统信息库会跟踪编译中的更改.
例如,如果设置-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-8C++用户指南2004年4月7.
5.
2定义搜索路径-I作为正常搜索路径的选项,您可以用选项-pti目录指定模板定义文件的搜索目录.
多个-pti标志定义了多个搜索目录,即搜索路径.
如果您使用-pti目录,则编译器在该路径查找模板定义文件并忽略-I标志.
因为-pti目录标志将源文件的搜索规则复杂化,所以使用-I选项代替-pti目录选项.
7.
6模板选项文件模板选项文件是用户提供的可选文件,包含了定位模板定义和控制实例重新编译所需的选项.
此外,选项文件提供了控制模板专用化和显式实例化的功能.
不过,因为C++现在支持在源代码中声明专用化和显式实例化所需的语法,所以您不需使用这些功能.

注–C++编译器以后发行的版本中将不支持模板选项文件.
该选项文件名为CC_tmpl_opt且位于SunWS_config目录内.
该选项文件是包含了大量条目的ASCII文本文件.
条目由关键字后跟所需的文本组成并用(;)终止.
尽管关键字不能分割,但是条目可以跨越多行.
7.
6.
1注释注释以#字符开头,并扩展到行尾.
注释内的文本被忽略.
7.
6.
2包括您可以通过包括选项文件,在多个模板数据库间共享选项文件.
该功能尤其适用于生成包含模板的库时.
处理期间,指定的选项文件完整地包括在当前选项文件中.
您可以具有多个include语句并将这些语句放置在选项文件的任何位置.
该选项文件也可以嵌套.
#行尾之前的注释文本被忽略.
include"options-file";第7章编译模板7-97.
6.
3源文件扩展名编译器使用缺省Cfront式样源文件定位器机制,所以您可以指定不同源文件供编译器进行搜索.
格式为:ext-list是以空格分开的格式的有效源文件扩展名列表,例如:当选项文件不存在该条目时,编译器搜索的有效扩展名为.
cc、.
c、.
cpp、.
C,.
cxx和.
c++.
7.
6.
4定义源位置可以使用definition选项文件条目显式指定定义源文件的位置.
在模板声明和定义文件名称不遵循标准Cfront式样约定时,请使用定义条目.
条目的语法为:name字段表明了选项条目有效的模板.
每个名称仅允许一个定义条目.
这种名称必须是简单的名称,限定的名称是不允许的.
而且括号、返回类型和参数列表是不允许的.
无论返回类型或参数为何,只有名称本身计数.
因此,定义条目可以应用到多个(可能重载)模板.
"file-n"列表字段指出了包含模板定义的文件.
文件的搜索使用了定义搜索路径.
文件名必须以引号("")封闭.
因为简单模板名称可以引用到不同文件中定义的不同模板,或因为单一模板可以在不同文件中定义,所以此时可以使用多个文件.
例如,如果func在三个文件中定义,则这三个文件必须在定义条目中列出.
nocheck字段在本节的结尾处描述.
在以下示例中,编译器在foo.
cc中定位并实例化模板函数foo.
这种情况下,定义条目是缺省搜索中冗余的条目.
extensions"ext-list";extensions".
CC.
c.
cc.
cpp";definitionnamein"file-1",["file-2".
.
.
,"file-n"][nocheck"options"];编码范例7-1冗余定义条目foo.
cctemplateTfoo(Tt){}CC_tmpl_optdefinitionfooin"foo.
cc";7-10C++用户指南2004年4月以下示例说明了静态数据成员的定义和简单名称的用法.
为fooref的定义提供的名称是简单名称,而不是限定名称(例如foo::fooref).
定义条目的原因是文件名称不是foo.
cc(或某些其它可识别的扩展名),并且不能使用缺省Cfront式样搜索规则来定位.
以下示例说明了模板成员函数的定义.
如示例所述,成员函数可以完全与静态成员初始化程序一样处理.
以下示例说明了两个不同源文件中模板函数的定义.
在本示例中,编译器必须能够找到重载函数func()的两个定义.
定义条目告知了编译器查找对应函数定义的位置.
编码范例7-2静态数据成员的定义和简单名称的用法foo.
htemplateclassfoo{staticT*fooref;};foo_statics.
cc#include"foo.
h"templateT*foo::fooref=0CC_tmpl_optdefinitionfoorefin"foo_statics.
cc";编码范例7-3模板成员函数定义foo.
htemplateclassfoo{T*foofunc(T);};foo_funcs.
cc#include"Foo.
h"templateT*foo::foofunc(Tt){}CC_tmpl_optdefinitionfoofuncin"foo_funcs.
cc";编码范例7-4不同源文件中模板函数的定义foo.
htemplateclassfoo{T*func(Tt);T*func(Tt,Tx);};foo1.
cc#include"foo.
h"templateT*foo::func(Tt){}foo2.
cc#include"foo.
h"templateT*foo::func(Tt,Tx){}CC_tmpl_optdefinitionfuncin"foo1.
cc","foo2.
cc";第7章编译模板7-11有时某些编译标志更改时,并不需要重新编译.
您可以使用definition选项文件条目的nocheck字段来避免不必要的重新编译,该字段告知了编译器和模板数据库管理器检查依存关系时忽略某些选项.
如果不想要编译器因特定命令行标志的增加或减少而重新实例化模板函数,则请使用nocheck标志.
条目的语法为:选项必须用引号("")封闭.
在以下示例中,编译器在foo.
cc中定位并实例化模板函数foo.
如果以后需要重新实例化检查,则编译器将忽略-g选项.
7.
6.
5模板专用化条目直到最近,C++语言才不提供专用化模板的机制,因此每个编译器提供自己的机制.
本节描述了使用前一个版本的C++编译器机制的模板专用化.
仅在兼容模式中(-compat[=4])支持该机制.
special条目告知了编译器给定函数是专用化函数,并且编译器遇到该函数时不需实例化.
使用编译时实例化方法时,使用选项文件中的special条目来预先注册专用化.
语法为:该声明是没有返回类型的合法C++式样的声明.
例如:definitionnamein"file-1"[,"file-2".
.
.
,"file-n"][nocheck"options"];编码范例7-5nocheck选项foo.
cctemplateTfoo(Tt){}CC_tmpl_optdefinitionfooin"foo.
cc"nocheck"-g";special声明;编码范例7-6special条目foo.
htemplateTfoo(Tt){};main.
cc#include"foo.
h"CC_tmpl_optspecialfoo(int);7-12C++用户指南2004年4月前面的选项文件通知了编译器模板函数foo()不应为类型int实例化,还通知了专用版本是由用户提供的.
如果没有选项文件中的该条目,那么函数不必实例化并且可能会导致错误:在前面的示例中,编译器编译main.
cc时,因为编译器已找到定义,所以可以正确使用专用版本的foo.
不过编译file.
cc时,因为编译器不知道foo存在于main.
cc中,所以编译器实例化自身版本的foo.
在大多数情况下,该过程会在链接期间导致多重定义符号,但是在某些情况下(尤其是库),使用错误的函数会导致运行时错误.
如果您使用函数的专用版本,则应注册那些版本.
special条目可以重载,如以下示例所示:要专用化模板类,请将模板参数包括在special条目中:编码范例7-7何时应使用special条目的示例foo.
htemplateTfoo(Tt){returnt+t;}file.
cc#include"foo.
h"intfunc(){returnfoo(10);}main.
cc#include"foo.
h"intfoo(inti){returni*i;}//专用化intmain(){intx=foo(10);inty=func();return0;}编码范例7-8重载special条目foo.
htemplateTfoo(Tt){}main.
cc#include"foo.
h"intfoo(inti){}char*foo(char*p){}CC_tmpl_optspecialfoo(int);specialfoo(char*);编码范例7-9专用化模板类foo.
htemplateclassFoo{.
.
.
variousmembers.
.
.
};main.
cc#include"foo.
h"intmain(){Foobar;return0;}CC_tmpl_optspecialclassFoo;第7章编译模板7-13如果模板类成员是静态成员,则您必须将关键字static包括在专用化条目中:编码范例7-10专用化静态模板类成员foo.
htemplateclassFoo{public:staticTfunc(T);};main.
cc#include"foo.
h"intmain(){Foobar;return0;}CC_tmpl_optspecialstaticFoo::func(int);7-14C++用户指南2004年4月8-1第8章异常处理本章讨论了C++编译器如何实现异常处理.
您可以在第11-2页的第11.
2节"在多线程程序中使用异常"找到其他一些信息.
更多关于异常处理的信息,请参阅BjarneStroustrup编著的TheC++ProgrammingLanguage第三版(Addison-Wesley,1997).
8.
1同步和异步异常异常处理设计用于仅支持同步异常,例如数组范围检查.
术语同步异常意味着异常仅可以来源于throw表达式.
C++标准支持具有终止模型的同步异常处理.
终止意味着异常抛出后,控制不会返回到抛出点.
异常处理没有设计用于直接处理诸如键盘中断等异步异常.
不过,如果小心处理,在出现异步事件时也可以进行异常处理.
例如,要用信号进行异常处理工作,您可以编写设置全局变量的信号处理程序,并创建另外一个例程来定期轮询该变量的值,当该变量值发生更改时抛出异常.
不能从信号处理程序抛出异常.
8-2C++用户指南2004年4月8.
2指定运行时错误有五个与异常有关的运行时错误消息:I没有异常处理程序I未预料到的异常抛出I异常只能在处理程序中重新抛出I在解开堆栈时,析构函数必须处理自身的异常I内存不足在运行时检测到错误时,错误消息显示了当前异常的类型和这五个错误消息之一.
缺省情况下,预定义的函数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-4C++用户指南2004年4月为了与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超过自动变量或临时变量的初始化或不常用销毁.
不能从信号处理程序抛出异常.
//头文件,用于转换#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-58.
6生成具有异常的共享库永远不要使用具有包含C++代码的程序的-Bsymbolic,相反要使用链接程序映射文件.
使用-Bsymbolic时,在不同模块中的引用可以绑定到被假设为全局对象内容的不同副本中.
异常机制依赖于对地址的比较.
如果某内容具有两个副本,它们的地址不相同,则异常机制可能会失败,这是由于异常机制依赖对假设为唯一地址内容的比较.

使用dlopen打开共享库时,必须将RTLD_GLOBAL用于异常.
8-6C++用户指南2004年4月9-1第9章类型转换操作本章讨论了C++标准中较新的类型转换操作符:const_cast,reinterpret_cast,static_cast和dynamic_cast.
类型转换可以将对象或值从一种类型转换为另一种类型.
这些类型转换操作比以前的类型转换操作更好控制.
dynamic_cast操作符提供了一种方法来检查到多态类的指针的实际类型.
您可以用文本编辑器来搜索所有新样式的类型转换(搜索_cast),而查找旧样式的类型转换需要语法分析.
此外,这些新的类型转换全部执行传统类型转换符号允许的类型转换子集.
例如,const_cast(v)可以写为(int*)v.
新的类型转换仅将各种可用的操作分类以更清楚地表示您的意图,并允许编译器提供更完善的检查.
类型转换操作符是始终启用的,不能禁用.
9-2C++用户指南2004年4月9.
1const_cast表达式const_cast(v)可用于更改指针或引用的const或volatile限定符.
(在新样式的类型转换中,只有const_cast可以去掉const限定符.
)T必须是指针、引用或指向成员的指针的类型.
9.
2reinterpret_cast表达式reinterpret_cast(v)更改了表达式v值的解释.
它可用于指针和整数类型之间、无关的指针类型之间、指向成员的指针类型之间及指向函数的指针类型之间的类型转换.
使用reinterpret_cast操作符后可得到未定义或依赖于具体实现的结果.
以下几点描述了最确定的行为:I指向数据对象或函数的指针(但不是指向成员的指针)可以转换为足够包含该指针的任何整数类型.
(long类型总是足以包含C++编译器支持的体系结构上的指针值.
)转换回初始类型时,该指针值将与原始指针值相比较,看是否相等.
I指向(非成员)函数的指针可以转换为指向不同(非成员)函数类型的指针.
如果转换回原始类型,指针值将与原始指针相比较.
I假设新类型的对齐要求没有原始类型严格,则指向对象的指针可以转换为指向不同对象类型的指针.
转换回初始类型时,该指针值将与原始指针值相比较,看是否相等.

I如果"指向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-3I如果T1和T2都是函数类型或都是对象类型,则"指向T1类型X成员的指针"类型右值可以显式转换为"指向T2类型Y成员的指针"类型右值.
I在所有允许的情况下,空指针类型转换为不同的空指针类型后仍然是空指针.

Ireinterpret_cast操作符不能用于转换const,转换const要使用const_cast.
Ireinterpret_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-4C++用户指南2004年4月9.
4动态类型转换指向类的指针(或引用)可以实际指向(引用)从该类派生的任何类.
有时希望指向完全派生类的指针,或指向完整对象的某些其它子对象.
动态类型转换可以实现这些功能.
注–用兼容模式(-compat[=4])编译时,如果程序使用动态类型转换,您必须用-features=rtti编译.
动态类型转换将指向一个类T1的指针(或引用)转换到指向另一个类T2的指针(引用).
T1和T2必须位于同一分层结构,类必须是可访问的(经公共派生),并且转换必须要是明确的.
此外,除非转换是从派生类到该派生类的一个基类,包括T1和T2的分层结构的最小部分必须是多态的(至少具有一个虚函数).
在表达式dynamic_cast(v)中,v是要被类型转换的表达式,而T是要转换到的类型.
T必须是完整类的类型(其中一个的定义是可视的)的指针或引用,或指向cvvoid、常量、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章类型转换操作9-59.
4.
3将分层结构向下或交叉类型转换向下或交叉类型转换分层结构时,分层结构必须是多态的(具有虚函数).
结果在运行时检查.
向下或交叉类型转换分层结构时,从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-6C++用户指南2004年4月然而该示例失败,原因是基类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);//STATICERROR: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-8C++用户指南2004年4月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-2C++用户指南2004年4月10.
2使用内联函数使用扩展内联而不使用正常调用时,对小而快速的函数的调用可以更小更快速.
反过来,如果使用扩展内联而不建立分支,则对又长又慢的函数的调用会更大更慢.
另外,只要函数定义更改,就必须重新编译对内联函数的所有调用.
因此,使用内联函数时要格外小心.
在期望更改函数定义而且重新编译所有调用方很费时间时,请不要使用内联函数.
否则,如果扩展函数内联的代码比调用函数的代码少,或使用函数内联时应用程序执行速度显著提高,那么可以使用内联函数.
编译器不能内联所有函数调用,因此使用最耗时的函数内联会需要某些源码的更改.
使用+w选项以了解何时不发生函数内联.
在以下情况中,编译器将不会内联函数:I函数包含了复杂控制构造,例如循环、switch语句和try/catch语句.
这些函数很少多次执行复杂控制构造.
要内联这种函数,请将函数分割为两部分,里边的部分包含了复杂控制构造,而外边的部分决定了是否调用里边的部分.
即使编译器可以内联完整函数,从函数常用部分中分隔出不常用部分的这种技术也可以改善性能.

I内联函数体又大又复杂.
因为对函数体内其它内联函数的调用,或因为隐式构造函数和析构函数调用(通常发生在派生类的构造函数和析构函数中),所以简单函数体可以非常复杂.
对于这种函数,内联扩展很少提供显著的性能改善,所以函数一般不内联.
I内联函数调用的参数既大又复杂.
对于内联成员函数调用的对象是内联函数调用的自身这种情况,编译器特别敏感.
要内联具有复杂参数的函数,只需将函数参数计算到局部变量并将变量传递给函数.
10.
3使用缺省运算符如果类定义不声明无参数的构造函数、复制构造函数、复制赋值运算符或析构函数,那么编译器将隐式声明它们.
它们都是调用的缺省运算符.
类似C的结构具有这些缺省运算符.
编译器生成缺省运算符时,可以了解大量关于需要处理的工作和可以产生优良代码的工作.
这种代码通常比用户编写的代码的执行速度快,原因是编译器可以利用汇编级功能的优点,而程序员则不能利用该功能的优点.
因此缺省运算符执行所需的工作时,程序不能声明这些运算符的用户定义版本.
缺省运算符是内联函数,因此内联函数不合适时不使用缺省运算符(参阅上一节).
否则,缺省运算符是合适的:I用户编写的无参数构造函数仅为构造函数的基对象和成员变量调用无参数构造函数.

有效的基元类型具有"不执行任何操作"无参数构造函数.
I用户编写的复制构造函数仅复制所有的基对象和成员变量.
第10章改善程序性能10-3I用户编写的复制赋值运算符仅复制所有的基对象和成员变量.
I用户编写的析构函数可以为空.
某些C++编程手册建议编写类的程序员始终定义所有的运算符,以便该代码的任何读者都能了解该程序员没有忘记考虑缺省运算符的语义.
显然,该建议与以上讨论的优化有冲突.
这种冲突的解决方案是在代码中放置注释以表明类正使用缺省运算符.

10.
4使用值类包括结构和联合在内的C++类通过值来传递和返回.
对于Plain-Old-Data(POD)类,C++编译器需要像C编译器一样传递结构.
这些类的对象是直接传递的.
对于用户定义复制构造函数的类的对象,编译器需要构造对象的副本,将指针传递给副本,并在返回后销毁副本.
这些类的对象是间接传递的.
编译器也可以选择介于这两个要求之间的类.
不过,该选择影响二进制的兼容性,因此编译器对每个类的选择必须保持一致.

对于大多数编译器,直接传递对象可以加快执行速度.
这种执行速度的改善对于小值类(例如复数和概率值)来说尤其明显.
有时为了改善程序执行效率,您可以设计更可能直接传递而不是间接传递的类.
在兼容模式(-compat[=4])中,如果类具有以下任何一条,则间接传递该类:I用户定义的构造函数I虚函数I虚拟基类I间接传递的基I间接传递的非静态数据成员否则,类被直接传递.
在标准模式(缺省模式)中,如果类具有以下任何一条,则间接传递该类:I用户定义的复制构造函数I用户定义的析构函数I间接传递的基I间接传递的非静态数据成员否则,类被直接传递.
10-4C++用户指南2004年4月10.
4.
1选择直接传递类尽可能直接传递类:I只要可能,就使用缺省构造函数,尤其是缺省复制构造函数.
I尽可能使用缺省析构函数.
缺省析构函数不是虚拟的,因此具有缺省析构函数的类通常不是基类.
I避免使用虚函数和虚拟基.
10.
4.
2在不同的处理器上直接传递类C++编译器直接传递的类(和联合)与C编译器传递结构(或联合)完全相同.
不过,C++结构和联合在不同的架构上进行不同的传递.
表10-1在不同架构上结构和联合的传递架构说明SPARCV7/V8通过在调用方内分配存储并将指针传递给该存储,传递并返回结构和联合.

(也就是说,所有的结构和联合都通过引用传递.
)SPARCV9不超过16个字节(32个字节)的结构在寄存器中传递.
通过在调用方内分配存储并将指针传递给该存储,联合和所有其它结构将被传递并返回.
(也就是说,小的结构在寄存器中传递,而联合和大的结构通过引用传递.
)因此,小值类与基元类具有相同的传递效率.
IA平台结构和联合通过在堆栈上分配空间并将参数复制到堆栈上来传递.
通过在调用方的帧中分配临时对象并作为隐式第一个参数传递临时对象的地址,返回结构和联合.
第10章改善程序性能10-510.
5缓存成员变量访问成员变量是C++成员函数的通用操作.
编译器必须经常从内存通过this指针装入成员变量.
因为值通过指针装入,所以编译器有时不能决定何时执行第二次装入或以前装入的值是否仍然有效.
在这些情况下,编译器必须选择安全但缓慢的方法,在每次访问成员变量时重新装入成员变量.

如下所示,可以通过在局部变量中显式缓存成员变量的值来避免不必要的内存重新装入:I声明局部变量并使用成员变量的值初始化该变量.
I在函数中成员变量的位置使用局部变量.
I如果局部变量变化,那么将局部变量的最终值赋值到成员变量.
不过,如果成员函数在该对象上调用另一个成员函数,那么该优化会产生意外的结果.
当值位于寄存器中时,这种优化最有效,而这种情况也与基元类型相同.
基于内存的值的优化也会很有效,因为减少的别名使编译器获得了更多的机会来进行优化.

如果成员变量经常通过引用(显式或隐式)来传递,那么优化可能无法取得预期的效果.
有时,类的目标语义需要成员变量的显式缓存,例如在当前对象和其中一个成员函数参数之间有潜在别名时.
例如:在使用以下内容调用时将产生意外的结果: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-6C++用户指南2004年4月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.
1libw.
so.
1=>/usr/lib/libw.
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-311.
3在线程之间共享C++标准库对象C++标准库(libCstd)是多线程安全的,这样可以确保在多线程环境中库内部正常工作.
您仍需要将各个线程之间要共享的库对象锁定起来(除iostreams和locale对象外).
例如,如果实例化字符串,然后创建新的线程并使用引用将字符串传递给线程.
因为要在线程之间显式共享这个字符串对象,所以您必须锁定对于该字符串的写访问.

(库提供的用于完成该任务的工具在下文中会有描述.
)另一方面,如果通过值将字符串传递给新的线程,则即使两个不同线程中的字符串通过RogueWave的"copyonwrite"技术共享表示方式,也不必担心是否锁定.
库将自动处理锁定.
只有通过在线程之间传递引用或使用全局或静态对象的方式使对象对于多线程显式可用时,您才需要锁定.
下文描述了C++标准库内部使用的锁定(同步)机制,该机制用于确保在多线程下出现正确的行为.
_RWSTDMutex和_RWSTDGuard这两个同步类提供了实现多线程安全的机制.
_RWSTDMutex类通过下列成员函数提供与平台无关的锁定机制:Ivoidacquire()获取对自身的锁定,或在锁定之前处于阻塞状态.
Ivoidrelease()释放对自身的锁定.
class_RWSTDMutex{public:_RWSTDMutex();~_RWSTDMutex();voidacquire();voidrelease();};11-4C++用户指南2004年4月_RWSTDGuard类是一个方便的包装类,其中封装有_RWSTDMutex类的对象.
_RWSTDGuard对象尝试在其构造函数中获取封装的互斥(抛出std::exceptiononerror派生的::thread_error类型的异常),并在析构函数中释放互斥(析构函数从不会抛出异常).
另外,您可以使用宏_RWSTD_MT_GUARD(mutex)(以前的_STDGUARD)在多线程生成中有条件地创建_RWSTDGuard的对象.
该对象保护代码块的其余部分,并在该代码块中定义为可同时被多个线程执行.
在单线程生成中,宏扩展到空表达式中.

class_RWSTDGuard{public:_RWSTDGuard(_RWSTDMutex&);~_RWSTDGuard();};第11章生成多线程程序11-5以下示例说明了这些机制的使用.
#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;////在guard中调用析构函数时,释放对I的锁定.
//}11-6C++用户指南2004年4月11.
4在多线程环境中使用传统iostream本节描述了如何使用libC和libiostream库的iostream类在多线程环境中进行输入输出操作(I/O).
本节还提供了如何通过从iostream类派生来扩展库的功能.
不过本节并不是用C++编写多线程代码的指南.
此处的讨论只适用于旧的iostream(libC和libiostream),但不适用于libCstd(即新的iostream,它是C++标准库的一部分).
iostream库允许其接口被多线程环境下的应用程序使用,而这些程序在运行Solaris操作环境版本2.
6、7或8下使用多线程功能.
如果应用程序使用以前版本库的单线程功能,那么该应用程序不会受到影响.
如果库在线程环境中能正常工作,就将其定义为是多线程安全的.
通常,此处的"正确"意味着所有的公用函数都是可重入的.
iostream库提供了对多线程的保护,多线程尝试修改由多个线程共享的对象(即C++类的实例)状态.
不过,iostream对象的多线程安全范围限制在执行对象公用成员函数的周期内.
注–应用程序不会因为使用libC库中的多线程安全对象而自动保证是多线程安全的.
仅当应用程序在多线程环境中能按预期执行时,才将其定义为是多线程安全的.

11.
4.
1多线程安全的iostream库的组织多线程安全的iostream库的组织与其它版本的iostream库稍有不同.
库的输出接口指的是iostream类的公共的和受保护的成员函数以及可用的基类集合,这一点与其它版本的库相同,但各个版本的类分层结构是不同的.
详细信息请参阅第11-13页的第11.
4.
2节"接口更改为iostream库".
第11章生成多线程程序11-7初始核心类以unsafe_前缀来重命名.
表11-1中列出了iostream软件包中的核心类.
每个多线程安全类都是从基类stream_MT派生的.
每个多线程安全类(除了流缓冲外)也是从现有unsafe_基类派生的.
示例如下:stream_MT类提供了要求的互斥(mutex)锁定,以便每个iostream类都是多线程安全的.
此外还提供了用于动态启用和禁用锁定的功能,以便多线程安全的属性可以动态更改.
unsafe_类中包括I/O转换和缓冲区管理的基本功能,加到库中的多线程安全只限于派生类.
每个类的多线程安全版本包含了与unsafe_base类相同的受保护的和公共的成员函数.
多线程安全版本的类中每个成员函数都像包装器一样锁定对象,调用unsafe_base类中的相同函数,然后解锁对象.
注–流缓冲类不是从不安全的类派生的.
流缓冲的公共的和受保护的成员函数是可以通过锁定而重入的.
此外同时也提供了带有_unlocked后缀的不锁定版本.
表11-1iostream初始核心类类说明stream_MT多线程安全类的基类.
streambuf缓冲区的基类.
unsafe_ios该类包含各种流类通用的状态变量;例如,错误和格式化状态.
unsafe_istream该类支持流缓冲检索到的字符序列的有格式和无格式的转换.
unsafe_ostream该类支持存储在流缓冲中的字符序列的有格式和无格式的转换.
unsafe_iostream该类合并unsafe_istream和unsafe_ostream类用于双向操作.
classstreambuf:publicstream_MT{.
.
.
};classios:virtualpublicunsafe_ios,publicstream_MT{.
.
.
};classistream:virtualpublicios,publicunsafe_istream{.
.
.
};11-8C++用户指南2004年4月11.
4.
1.
1公共转换例程iostream接口中增加了一组可重入的多线程安全的公共函数.
用户指定的缓冲区被作为每个函数的附加参数.
这些函数如下所述:注–用来确保与早期版本libC兼容的iostream库的公共转换例程(oct、hex、dec、chr和form)都不是多线程安全的.
表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章生成多线程程序11-911.
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操作所在的临界区进行错误检查.
以下示例说明了如何检查错误:在该示例中,stream_locker对象sl的构造函数锁定了istream对象istr.
在read_number终止时调用的析构函数sl解锁istr.
编码范例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-10C++用户指南2004年4月获取通过上次未格式化输入操作提取的字符要成为多线程安全的,必须在互斥使用istream对象的线程内,并在包括上次输入操作和gcount调用的执行周期内,调用gcount函数.
以下示例说明了对gcount的调用:在该示例中,stream_locker类的lock和unlock成员函数定义了程序中的互斥区域.
编码范例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章生成多线程程序11-11用户定义的I/O操作要成为多线程安全的,为用户定义类型定义的I/O操作必须锁定以定义临界区(这些类型涉及到单个操作的特定顺序).
以下示例说明了用户定义的I/O操作:11.
4.
1.
4减少多线程安全类的性能重载在本版本的libC库中使用多线程安全类(即使是在单线程应用程序中),也会导致一定的性能重载.
但是您可以使用libC中的unsafe_类以避免此重载.
范围转换运算符可以用于执行基unsafe_类的成员函数,例如:注–unsafe_类不能在多线程应用程序中安全地使用.
编码范例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);*this>>name;*this>>id;*this>>gpa;returnthis->fail()==0;}cout.
unsafe_ostream::put('4');cin.
unsafe_istream::read(buf,len);11-12C++用户指南2004年4月您可以使cout和cin对象unsafe,然后使用正常操作来代替使用unsafe_类.
这会稍微降低性能.
以下示例说明了如何使用unsafecout和cin:iostream对象是多线程安全的时,将提供互斥锁定来保护对象的成员变量.
该锁定给仅在单线程环境中执行的应用程序增加了不必要的重载.
要提高性能,您可以动态切换iostream对象的多线程安全.
以下示例使iostream对象多线程不安全:您可以在iostream没有被线程共享的代码中安全地使用多线程不安全的流;例如,在只有一个线程的程序中,或在每个iostream都是线程专用的程序中.
如果将同步显式插入到程序中,那么也可以在线程共享iostream对象的环境中安全使用多线程不安全的iostreams.
以下示例说明了该技术:其中generic_lock和generic_unlock函数可以是使用诸如互斥、信号量或读取器/写入器锁定等基元的任何同步机制.
注–LibC提供的stream_locker类是实现这一目的的最佳机制.
更多信息请参阅第11-16页的第11.
4.
5节"对象锁定".
编码范例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-6在多线程不安全的对象中使用同步generic_lock();fs.
set_safe_flag(stream_MT::unsafe_object);.
.
.
执行各种i/o操作generic_unlock();第11章生成多线程程序11-1311.
4.
2接口更改为iostream库本节讨论了使iostream库具有多线程安全而进行的接口更改.
11.
4.
2.
1新增类下表列出了增加到libC接口的新类.
11.
4.
2.
2新增类的分层结构下表列出了增加到iostream接口的新增类的分层结构.
编码范例11-7新增类stream_MTstream_lockerunsafe_iosunsafe_istreamunsafe_ostreamunsafe_iostreamunsafe_fstreambaseunsafe_strstreambase编码范例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-14C++用户指南2004年4月11.
4.
2.
3新增函数下表列出了增加到iostream接口的新函数.
编码范例11-9新增函数classstreambuf{public:intsgetc_unlocked();voidsgetn_unlocked(char*,int);intsnextc_unlocked();ntsbumpc_unlocked();voidstossc_unlocked();intin_avail_unlocked();iintsputbackc_unlocked(char);intsputc_unlocked(int);intsputn_unlocked(constchar*,int);intout_waiting_unlocked();受保护的:char*base_unlocked();char*ebuf_unlocked();intblen_unlocked();char*pbase_unlocked();char*eback_unlocked();char*gptr_unlocked();char*egptr_unlocked();char*pptr_unlocked();voidsetp_unlocked(char*,char*);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);第11章生成多线程程序11-1511.
4.
3全局和静态数据多线程应用程序中的全局和静态数据不会在各个线程之间安全地共享.
尽管线程独立执行,但它们在进程中共享对全局和静态对象的访问.
如果一个线程修改了这种共享对象,那么进程中的其它线程将观察该更改,使得状态难以维持.
在C++中,类对象(类的实例)靠其成员变量的值来维持状态.
如果类对象被共享,那么该类对象将易于被其它线程更改.
多线程应用程序使用iostream库并包含iostream.
h时,缺省情况下标准流cout、cin、cerr和clog被定义为全局共享对象.
因为iostream库是多线程安全的,所以该库将在执行iostream对象的成员函数时保护共享对象的状态不受其它线程的访问或更改.
不过,对象的多线程安全范围被限制在执行对象公用成员函数的周期内.
例如,};classstrstreambuf:publicstreambuf{public:intfreeze_unlocked();char*str_unlocked();};unsafe_ostream&endl(unsafe_ostream&);unsafe_ostream&ends(unsafe_ostream&);unsafe_ostream&flush(unsafe_ostream&);unsafe_istream&ws(unsafe_istream&);unsafe_ios&dec(unsafe_ios&);unsafe_ios&hex(unsafe_ios&);unsafe_ios&oct(unsafe_ios&);char*dec_r(char*buf,intbuflen,longnum,intwidth)char*hex_r(char*buf,intbuflen,longnum,intwidth)char*oct_r(char*buf,intbuflen,longnum,intwidth)char*chr_r(char*buf,intbuflen,longchr,intwidth)char*str_r(char*buf,intbuflen,constchar*format,intwidth=0);char*form_r(char*buf,intbuflen,constchar*format,.
.
.
)intc;cin.
get(c);编码范例11-9新增函数(续下)11-16C++用户指南2004年4月在get缓冲区中获得下一个字符,并更新ThreadA中的缓冲区指针.
不过,如果ThreadA中的下一条指令是另一个get调用,那么libC库将不能保证按序返回下一个字符.
这是因为,例如ThreadB可能也会在ThreadA的两个get调用的间隙中执行get调用.
更多关于共享对象和多线程问题的处理策略,请参阅第11-16页的第11.
4.
5节"对象锁定".
11.
4.
4序列执行通常当使用iostream对象时,I/O操作的序列必须是多线程安全的.
例如,如下所示代码:涉及到cout流对象的三个成员函数的执行.
由于cout是共享对象,所以必须像临界区那样独立执行序列,使其能在多线程环境中正常工作.
要独立对iostream类对象执行操作序列,您必须使用某些形式的锁定.
libC库提供了stream_locker类来锁定iostream对象的操作.
关于stream_locker类的信息,请参阅第11-16页的第11.
4.
5节"对象锁定".
11.
4.
5对象锁定解决共享对象和多线程的最简单策略是通过确保iostream对象被锁定到线程,从而避免此类问题的发生.
例如,I在线程的函数入口内局部声明对象.
I在线程特定数据中声明对象.
(关于如何使用线程特定的数据,请参阅thr_keycreate(3T)手册页.
)I使流对象专用于特定线程.
按照约定,对象线程是private.
不过在许多情况下(例如缺省共享标准流对象),使对象专用于某线程是不可能的,这就需要其它的策略了.
要独立对iostream类对象执行操作序列,您必须使用某些形式的锁定.
即使对于单线程应用程序,锁定也会增加某些重载.
是否增加锁定或使iostream对象专用于某个线程取决于为应用程序选择的线程模型:线程是独立的还是协同操作的I如果每个独立的线程使用自己的iostream对象来生成或使用数据,那么这些iostream对象专用于各自所属的线程并且不需要锁定.
I如果线程是协同操作的(即,共享同一个iostream对象),那么必须对共享对象进行同步访问,而且必须使用某种形式的锁定以使得序列化操作独立化.

cout#includevoidlock_example(fstream&fs){constintlen=128;charbuf[len];intoffset=48;stream_lockers_lock(fs,stream_locker::lock_now);打开文件fs.
seekg(offset,ios::beg);fs.
read(buf,len);}11-18C++用户指南2004年4月使用stream_locker对象的替代方法是显式定义互斥区域.
在以下示例中,要使I/O操作和随后的错误检查独立化,使用了vbstream_locker对象的lock和unlock成员函数调用.
更多信息请参阅stream_locker(3CC4)手册页.
11.
4.
6多线程安全类您可以通过派生新的类来扩展或专用化iostream类.
如果由派生类实例化的对象被用于多线程环境中,那么这些类必须是多线程安全的.
派生多线程安全类时的注意事项包括:I通过保护对象的内部状态避免多线程的修改,使得类对象成为多线程安全的.
要实现这一目的,请序列化对成员变量的公共访问,并使用互斥锁定来保护成员函数.

I使用stream_locker对象,令多线程安全基类的成员函数调用序列独立化.
I通过在stream_locker对象定义的临界区中使用流缓冲的成员函数_unlocked,避免锁定重载.
I函数被应用程序直接调用时,锁定流缓冲类的公共虚函数.
这些函数包括:xsgetn、underflow、pbackfail、xsputn、overflow、seekoff和seekpos.
I使用ios类中的成员函数iword和pword来扩展ios对象的格式化状态.
不过,如果多个线程共享对iword或pword函数的相同索引,将会发生问题.
要使线程成为多线程安全的,请使用相应的锁定方案.
I锁定返回成员变量的值大于char的成员函数.
编码范例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){//每次读取一行instr.
getline(ibuf,thread_bufsize-1,"\n");第11章生成多线程程序11-21if(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(){coutintmain(){std::cout来代替.
不能在兼容模式下使用.
在兼容模式下,必须在链接时显式请求complex库.
在标准模式下,complex库包括在libCstd中,并且是缺省链接的.
标准模式没有complex.
h头文件.
在C++4.
2中,"complex"是类的名称,但是在标准C++中,"complex"是模板名称.
不可能提供可使旧的代码不加修改就可工作的typedef.
因此,为使用复数的4.
2版编写的代码需要某些简单的编辑,以便使用标准库.
例如,以下代码是为4.
2版编写的,并将在兼容模式下编译.
以下示例在兼容模式下编译并链接ex1.
cc,然后执行该程序.
此处将ex1.
cc重写为ex2.
cc以便在标准模式下编译://文件ex1.
cc(兼容模式)#include#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第12章使用库12-1312.
7.
2不可以替换的内容标准头文件、和与编译器本身和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头文件.
例如:编译期间,-library=no%Cstd选项防止搜索编译器本身版本的这些头文件所在的目录.
对于每个程序或库链接,使用-library=no%Cstd选项防止查找编译器本身的libCstd,-L选项指向替换库所在目录,-l选项指定替换库.
示例:或者,可以直接使用库的完整路径名称,忽略使用-L和-l选项.
例如:链接期间,-library=no%Cstd选项防止链接编译器本身版本的libCstd.
example%CC-I/opt/mycstd/include-library=no%Cstd.
.
.
(编译)example%CC-library=no%Cstd-L/opt/mycstd/lib-lmyCstd.
.
.
(链接)example%CC-library=no%Cstd/opt/mycstd/lib/libmyCstd.
a.
.
.
(链接)12-14C++用户指南2004年4月12.
7.
5标准头文件实现C具有17个标准头文件(、、和其它).
这些头文件作为Solaris操作环境的一部分,位于/usr/include目录.
C++具有这些相同的头文件,另外要求在全局名称空间和std名称空间中显示不同声明的名称.
在Solaris操作环境版本8之前的版本中,C++编译器提供了本身版本的这些头文件来替换/usr/include目录中的头文件.
C++也具有每个C标准头文件(、、和其它)的第二个版本,不同声明的名称仅显示在名称空间std中.
最后,C++增加了32个自己的标准头文件(、、和其它).
标准头文件的明显实现将C++源码中找到的名称用作包括的文本文件的名称.
例如,标准头文件(或)在某些目录中引用名为string(或string.
h)的文件.
这种明显实现有以下缺点:I如果没有文件名后缀,则不能搜索头文件或创建头文件的makefile规则.
I如果在编译器命令行上输入-I/usr/include,则不能获取Solaris2.
6和Solaris7操作环境标准C头文件的正确版本,原因是在搜索编译器本身包括的目录之前会搜索/usr/include.
I如果具有名为string的目录或可执行程序,那么会错误地找到该目录或程序,而不是找到标准头文件.
I在Solaris8操作环境以前的Solaris操作环境上,启用.
KEEP_STATE时,makefile的缺省相关性会导致尝试将标准头文件替换为可执行程序.
(没有后缀的文件缺省假定为要生成的程序.
)为了解决这些问题,编译器include目录包含了与头文件具有相同名称的文件,还有到具有唯一后缀.
SUNWCCh的符号链接(SUNW是所有编译器相关软件包的前缀,CC是C++编译器,h是头文件的通用后缀).
指定后,编译器将其重写到并搜索该名称.
后缀名只会在编译器自己的include目录中才能找到.
如果这样找到的文件是符号链接(正常情况下),编译器就会去掉链接,并将结果(这里是string)用作错误消息和调试器引用的文件名.
忽略文件的相关性信息时,编译器使用带后缀的名称.
仅当出现在尖括号中且无需指定任何路径时,17种标准C头文件和32种标准C++头文件的两种格式才会发生名称重写.
如果使用引号来代替尖括号指定任何路径组件或其它某些头文件,就不会有重写发生.
第12章使用库12-15下表说明了通常的情况.
如果编译器未找到header.
SUNWCCh,那么编译器将会重新搜索以查找#include指令提供的名称.
例如,如果给定指令#include,编译器就会尝试找到名为string.
SUNWCCh的文件.
如果搜索失败,编译器就会查找名为string的文件.
12.
7.
5.
1替换标准C++头文件由于在第12-14页的第12.
7.
5节"标准头文件实现"中描述的搜索算法,所以不必提供第12-13页的第12.
7.
3节"安装替换库"中所述替换头文件的SUNWCCh版本.
但是会遇到某些上文所述的问题.
如果是这样的话,建议为每个无后缀的头文件增加带有后缀.
SUNWCCh的符号链接.
也就是说,对于文件utility,您可以运行命令当编译器第一次查找utility.
SUNWCCh时,将会找到它,而不会和其它名为utility的文件或目录混淆.
12.
7.
5.
2替换标准C头文件不支持替换标准C头文件.
如果仍然希望提供您自己的标准头文件版本,那么建议按以下步骤操作:I将所有替换头文件放置在一个目录中.
I在目录中创建每个替换头文件的.
SUNWCCh符号链接.
I通过在每次调用编译器时使用-I,搜索包含替换头文件的目录.
表12-3头文件搜索示例源码编译器搜索注释string.
SUNWCChC++字符串模板cstring.
SUNWCChCstring.
h的C++版本string.
h.
SUNWCChCstring.
hfcntl.
h不是标准C或C++头文件"string"string双引号,不是尖括号.
.
/string指定的路径example%ln-sutilityutility.
SUNWCCh12-16C++用户指南2004年4月例如,假定您具有和的替换.
请将文件stdio.
h和cstdio放置在目录/myproject/myhdr中.
在该目录中,运行如下命令:每次编译时使用-I/myproject/mydir选项.
告诫:I如果要替换任何C头文件,就必须成对替换.
例如,如果要替换,就也必须替换.
I替换头文件必须与被替换版本具有相同的效果.
这就是说,不同的运行时库(如libCrun、libC、libCstd、libc和librwtool)使用标准头文件中的定义来生成.
如果替换文件不匹配,那么程序可能无法工作.
example%ln-sstdio.
hstdio.
h.
SUNWCChexample%ln-scstdiocstdio.
SUNWCCh13-1第13章使用C++标准库当在缺省(标准)模式下编译时,编译器可以访问C++标准指定的整个库.
库组件包括了标准模板库(STL)和以下组件.
I字符串类I数字类I标准版本的流I/O类I基本内存分配I异常类I运行时类型信息术语STL没有正式的定义,但是通常理解为包括容器、迭代器以及算法.
以下标准库头的子集可以认为包含了STL.
IIIIIIIIIIIC++标准库(libCstd)基于版本2的RogueWave标准C++库.
该库仅在编译器的缺省模式(-compat=5)下可用,使用-compat[=4]选项时不支持该库.
C++编译器也支持STLport的标准库实现版本4.
5.
3.
libCstd仍然是缺省库,但作为替代,也可以使用STLport的产品.
更多信息请参阅第13-14页的第13.
3节"STLport".
如果需要使用自己的C++标准库版本代替编译器提供的版本,则可以通过指定-library=no%Cstd选项来实现.
替换与编译器一起发布的标准库是有风险的,不能保证产生预期的结果.
更多信息请参阅第12-12页的第12.
7节"替换C++标准库".
13-2C++用户指南2004年4月关于标准库的详细信息,请参阅StandardC++LibraryUser'sGuide和StandardC++ClassLibraryReference.
本书"开始之前"的"访问编译器和工具文档"在xxxi页曳梦时嘁肫骱凸ぞ呶牡涤在xxxi页中包含了访问该文档的信息.
关于可获得的C++标准库书籍的列表,请参阅"开始之前"的"其它公司出版的书籍"在xxxiv页"其它公司出版的书籍"在xxxiv页.
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-4C++用户指南2004年4月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复制一定范围内的元素count计算容器中满足给定条件的元素的数量表13-2C++标准库手册页(续下)手册页概述13-6C++用户指南2004年4月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初始化一个具有由值产生器类产生的值的容器get_temporary_buffer基于指针的基元,用于处理内存表13-2C++标准库手册页(续下)手册页概述第13章使用C++标准库13-7greater如果第一个参数比第二个参数大就返回真的二元函数对象greater_equal如果第一个参数大于或等于第二个参数就返回真的二元函数对象gslice用于表示数组的通用片的数字数组类gslice_array用于表示valarray的类BLAS片的数字数组类has_facet用于确定语言环境是否具有给定侧面的函数模板ifstream支持从命名文件读取或者从其它与文件描述符关联的设备读取includes已排序序列的一系列基本操作indirect_array用于表示从valarray中所选元素的数字数组类inner_product计算两个范围A和B的内积A*Binplace_merge将两个已排序的序列合并成为一个insert_iterator用于将项目插入集合而非覆盖集合的插入迭代器inserter用于将项目插入集合而非覆盖集合的插入迭代器ios一个包含所有流都需要的通用函数的基类ios_base定义成员类型并维护从它继承的类的数据iosfwd声明输入/输出库模板类并使之专用于宽字符和微型字符isalnum确定字符是字母还是数字isalpha确定字符是否为字母iscntrl确定字符是否为控制字符isdigit确定字符是否为十进制数字isgraph确定字符是否为图形字符islower确定字符是否为小写形式isprint确定字符是否可打印ispunct确定字符是否为标点符号isspace确定字符是否为空格istream帮助读取或者翻译由流缓冲区控制的序列输入istream_iterator具有istreams迭代器功能的流迭代器istreambuf_iterator从流缓冲区读取为其构造的连续字符istringstream支持读取内存中数组的basic_string类对象表13-2C++标准库手册页(续下)手册页概述13-8C++用户指南2004年4月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消息传送侧面messages_byname消息传送侧面min查找并返回一对值中的最小值min_element查找一个范围中的最小值表13-2C++标准库手册页(续下)手册页概述第13章使用C++标准库13-9minus返回用第一个参数减去第二个参数所得到的结果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向从其构造的流缓冲区对象写入连续的字符ostringstream支持写入类对象basic_stringostrstream写入一个在内存中的数组表13-2C++标准库手册页(续下)手册页概述13-10C++用户指南2004年4月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用新值替换集合中的元素replace_copy用新值替换集合中的元素,并将修改过的序列移入结果replace_copy_if用新值替换集合中的元素,并将修改过的序列移入结果replace_if用新值替换集合中的元素表13-2C++标准库手册页(续下)手册页概述第13章使用C++标准库13-11return_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>的typedefstringbuf将输入或者输出序列与任意字符序列关联表13-2C++标准库手册页(续下)手册页概述13-12C++用户指南2004年4月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-13wclog控制对流缓冲区的输出,该缓冲区与中声明的stderr对象关联wcout控制对流缓冲区的输出,该缓冲区与中声明的stdout对象关联wfilebuf将输入序列或输出序列与文件关联的类wfstream支持对命名文件的读取和写入,或者与文件描述符关联的设备的读取和写入wifstream支持从命名文件读取或者从其它与文件描述符关联的设备读取wios一个包含所有流都需要的通用函数的基类wistream帮助读取或者翻译由流缓冲区控制的序列输入wistringstream支持读取内存中数组的basic_string类对象wofstream支持写入命名文件或者其它与文件描述符关联的设备wostream帮助格式化或者写入由流缓冲区控制的序列输出wostringstream支持写入类对象basic_stringwstreambuf用于派生便于字符序列控制的各种流缓冲区的抽象基类wstringbasic_string、allocator>的typedefwstringbuf将输入或者输出序列与任意字符序列关联表13-2C++标准库手册页(续下)手册页概述13-14C++用户指南2004年4月13.
3STLport如果要使用libCstd的另一个标准库,请使用标准库的STLport实现.
您可以使用以下编译器选项关闭libCstd并使用替代的STLport库:I-library=stlport4更多信息请参阅第17-41页的第Q.
2.
48节"-library=l[,l.
.
.
]".
本发行版本包括称为libstlport.
a的静态归档和称为libstlport.
so的动态库.
决定是否使用STLport实现之前,请先考虑以下信息:ISTLport是开放源代码产品,并不能保证不同发行版本之间的兼容性.
也就是说,使用后续版本的STLport编译,可能导致使用STLport4.
5.
3编译的应用程序中断.
使用后续版本的STLport编译的二进制文件可能无法与使用STLport4.
5.
3编译的二进制文件链接.
Istlport4、Cstd和iostream库提供了自己的I/O流的实现.
使用-library指定其中的多个库,会导致不确定的程序行为.
I编译器的后续发行版本可能不包括STLport4,只包括更新版本的STLport.
编译器选项-library=stlport4在后续发行版本中可能不能使用,但是可以使用引用更新STLport版本的选项来替换该选项.
ISTLport不支持Tools.
h++.
ISTLport和缺省的libCstd是二进制级不兼容的.
如果使用标准库的STLport实现,那么您必须使用选项-library=stlport4编译和链接包括第三方库的所有文件.
这意味着不可以同时使用STLport实现和C++区间数学库libCsunimath.
原因是libCsunimath使用了缺省库头文件编译,而不用STLport来编译.
I如果决定使用STLport实现,那么一定要包括代码隐式引用的头文件.
允许标准头文件,但不必要包括另一个标准头文件作为实现的一部分.
I如果使用-compat=4编译,那么不能使用STLport实现.
第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-8C++用户指南2004年4月您还必须确保指针指向了分配的存储.
例如,下面列出了一个常见的错误:因为没有告知存储输入数据的位置,所以会导致程序的终止.
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(acin.
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-10C++用户指南2004年4月对于输出错误,您应该定期检查错误状态,并在发现非零状态时采取某些操作(诸如终止).
!
运算符用于测试iostream的错误状态.
例如,如果输入字母字符用于输入,以下代码就会产生输入错误:类ios具有用于错误处理的成员函数.
详细信息请参阅手册页.
14.
3.
10使用具有stdio的iostreams您可以与C++程序一起使用stdio,但是在程序内的相同标准流中混合iostreams和stdio时会发生某些问题.
例如,如果同时写入stdout和cout,就会发生独立缓冲并产生未预料的结果.
如果您既从stdin输入也从cin输入,问题就会更严重,因为独立缓冲会使输入成为垃圾.
要消除标准输入、标准输出和标准错误中的这种问题,就请在执行输入或输出前使用以下指令:它将所有预定义的iostreams与相应预定义的stdioFILE连接起来.
因为在预定义流作为连接的一部分成为无缓冲流时,性能会显著下降,所以该连接不是缺省连接.
可以在应用到不同文件的同一程序中同时使用stdio和iostreams.
也就是说,您可以使用stdio例程写入到stdout,也可以写入到附加到iostreams的其它文件.
只要不再尝试从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中的位设置,清除标志位向量.
11ostr>setiosflags(i)根据i中的位设置,设置标志位向量.
12ostr>setfill(c)将填充字符(用于填充字段)设置为c.
13ostr>setprecision(n)将浮点精度设置为n个数字.
14-16C++用户指南2004年4月14.
7.
1使用无格式控制器无格式控制器是具有如下功能的函数:I执行到流的引用I以某种方式操作流I返回控制器的参数由于移位运算符使用了为iostreams预定义的函数(指向它的指针),所以可以将函数放入输入或输出运算符的序列.
移位运算符调用函数,而不尝试读取或写入值.
将tab插入到ostream中tab控制器的示例如下所示:详细描述实现以下操作的方法:下面示例显示了无法用简单常量来实现的代码.
假设您要打开和关闭输入流的空白跳过.

那么您可以分别调用ios::setf和ios::unsetf打开和关闭skipws标志,或定义两个控制器.
ostream&tab(ostream&os){returnos#includeistream&skipon(istream&is){is.
setf(ios::skipws,ios::skipws);returnis;}istream&skipoff(istream&is){is.
unsetf(ios::skipws);returnis;}.
.
.
intmain(){intx,y;cin>>skipon>>x>>skipoff>>y;return1;}第14章使用传统iostream库14-1714.
7.
2参数化控制器包括在iomanip.
h中的其中一个参数化控制器名为setfill.
setfill设置用于填写字段宽度的字符.
该操作按照下例所示实现:参数化控制器的实现分为两部分:I控制器.
它使用一个额外的参数.
在前一个代码示例中,它使用了额外的int参数.
由于未给这个控制器函数定义移位运算符,所以您无法将它放至输入或输出操作序列中.
相反,您必须使用辅助函数applicator.
Iapplicator.
它调用该控制器.
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:I将输出流设置成十六进制模式.
I将long值插入到流中.
I恢复流的转换模式.
//文件setfill.
cc#include#include//私有控制器staticios&sfill(ios&i,intf){i.
fill(f);returni;}//公共applicatorsmanip_intsetfill(intf){returnsmanip_int(sfill,f);}14-18C++用户指南2004年4月使用类omanip_long的原因是该代码示例仅用于输出,而且代码操作的是long而不是int:14.
8Strstreams:数组的iostreams请参阅strstream(3CC4)手册页.
14.
9Stdiobufs:stdio文件的iostreams请参阅stdiobuf(3CC4)手册页.
14.
10流缓冲iostreams是两部分(输入或输出)系统的格式部分.
系统的其它部分由流缓冲组成,处理无格式字符流的输入和输出.
一般情况下可以通过iostreams来使用流缓冲,因此不必担心流缓冲的细节.
例如,要提高效率,避免错误处理或格式化内建的iostreams时,可以直接使用流缓冲.
#include#includestaticostream&xfield(ostream&os,longv){longsave=os.
setf(ios::hex,ios::basefield);os>toFile.
rdbuf();14-20C++用户指南2004年4月14.
11iostream手册页许多C++手册页阐述了iostream库的详细内容.
下表概述了每个手册页中的内容.
要访问传统iostream库手册页,请输入:example%man-s3CC4name表14-3iostream手册页概述手册页概述filebuf详细说明类filebuf的公用接口,该类从流缓冲派生并专用于文件.
关于从类流缓冲继承的功能的详细信息,请参阅sbufpub(3CC4)和sbufprot(3CC4)手册页.
通过类fstream使用filebuf类.
fstream详细说明类ifstream、ofstream和fstream的专用成员函数,该类用于使用文件的istream、ostream和iostream的专用版本.
ios详细说明类ios的各个部分,该类作为iostreams的基类.
该类也包含了所有流公共的状态数据.
ios.
intro介绍并概述了iostreams.
istream详细说明了以下内容:类istream的成员函数,这些函数支持从流缓冲获取的字符解释.
输入格式化定位描述为部分ostream类的函数.
某些相关函数相关控制器manip描述iostream库中定义的输入和输出控制器.
ostream详细说明了以下内容:类ostream的成员函数,这些函数支持写入到流缓冲的字符解释.
输出格式化定位描述为部分ostream类的函数某些相关函数相关控制器sbufprot描述了为从类流缓冲派生类编码的程序员所需的接口.
因为部分公用函数未在sbufprot(3CC4)手册页中进行讨论,所以还要参阅sbufpub(3CC4)手册页.
sbufpub详细说明类流缓冲的公用接口,尤其是流缓冲的公用成员函数.
该手册页包含了直接处理流缓冲类对象所需的信息,或是找到从流缓冲派生类继承的函数所需的信息.
如果您要从流缓冲派生类,还可以参阅sbufprot(3CC4)手册页.
第14章使用传统iostream库14-2114.
12iostream术语iostream库的描述中经常使用类似于一般编程方面所使用的术语,不过要具有一些特殊的含义.
下表定义了这些术语用在讨论iostream库时所表示的含义.
ssbuf详细说明类strstreambuf的专用的公用接口,该类从流缓冲派生并专用于处理字符数组.
关于从类流缓冲继承的函数的详细信息,请参阅sbufpub(3CC4)手册页.
stdiobuf包含了对类stdiobuf的最基本描述,该类从流缓冲派生并专用于处理stdioFILE.
关于从类流缓冲继承的函数详细信息,请参阅sbufpub(3CC4)手册页.
strstream详细说明strstream的专用成员函数,这些函数由iostream所派生类的集合实现并专用于处理字符数组.
表14-4iostream术语iostream术语定义缓冲该词具有两个含义,一个专用于iostream软件包,而另一个通常适用于输入和输出.
当特指iostream库时,缓冲是由类流缓冲定义的类型的对象.
通常,缓冲是一个内存块,用于为输入或输出有效地传输字符.
对于已缓冲的I/O,缓冲已满或被强制刷新之前,字符的实际传输会延迟.
无缓冲的缓冲是指流缓冲,其中没有上文定义的普通意义上的缓冲.
本章避免使用"缓冲"一词来指"流缓冲".
但手册页和其它C++文档还用术语缓冲来表示流缓冲.
提取从iostream获得输入的过程.
Fstream专用于文件的输入或输出流.
特指以courier字体打印时类iostream派生类.
插入发送输出到iostream中的过程.
iostream通常为输入或输出流.
iostream库该库的实现需要包括iostream.
h、fstream.
h、strstream.
h、iomanip.
h和stdiostream.
h.
因为iostream是面向对象的库,所以您应该扩展该库.
因此,处理iostream库的某些工作还未实现.
表14-3iostream手册页概述(续下)手册页概述14-22C++用户指南2004年4月流通常情况下指iostream、fstream、strstream或用户定义的流.
流缓冲包含字符序列的缓冲,该序列中带有put和/或get指针.
以courier字体打印时,它表示特定类.
否则,通常指类流缓冲或从流缓冲派生类的对象.

任何流对象包含了流缓冲所派生类型的一个对象或指向对象的指针.
Strstream专用于使用字符数组的iostream.
是指以courier字体打印时的特定类.
表14-4iostream术语(续下)iostream术语定义15-1第15章使用复数运算库复数是由实部和虚部组成的数字.
例如:在简并条件下,0+3i完全是虚数,通常写为3i,而5+0i完全是实数,通常写为5.
您可以使用complex数据类型来表示复数.
注–复数运算库(libcomplex)只用于兼容模式(-compat[=4]).
在标准模式(缺省模式)中,"C++标准库"libCstd包括具有简单功能的复数类.
15.
1复数库复数运算库将复数数据类型实现为新的数据类型并提供:IOperatorsI数学函数(为内建数字类型定义)I扩展(用于允许复数输入和输出的iostreams)I错误处理机制复数还可以表示为绝对值(或幅度)和参数(或角度).
该库提供了在实部虚部(笛卡尔)表示和幅度角度(极性)表示间进行转换的函数.
数字复共轭的虚部中符号相反.
3.
2+4i1+3i1+2.
3i15-2C++用户指南2004年4月15.
1.
1使用复数库要使用复数库,请将头文件complex.
h包括在程序中,然后使用-library=complex选项进行编译和链接.
15.
2类型complex复数运算库定义了一个类:complex.
类complex的对象可以容纳一个单一复数.
复数被构造为两部分:I实部I虚部类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算法运算符复数运算库定义了所有基本的算法运算符.
具体来说,以下运算符按一般方法和普通的优先级工作:减运算符(-)具有其通常的二元和一元含义.
此外,您可以按通常的方法使用以下运算符:I加法赋值运算符(+=)I减法赋值运算符(-=)I乘法赋值运算符(*=)I除法赋值运算符(/=)但是,若将以上四个运算符用于表达式,则不产生任何值.
例如,下列表达式无法进行运算:您还可以按照常规含义使用等号(==)和不等号(!
=).
将运算表达式中的实数和复数混合时,C++使用复数运算符函数并将实数转换为复数.
4.
533+0icomplexaComp(8.
999,2.
333);8.
999+2.
333icomplexa,b;.
.
.
if((a+=2)==0)非法b=a*=b;//非法15-4C++用户指南2004年4月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的类型并被下列复数运算库函数调用:IexpIlogIlog10IsinhIcoshcomplexpow(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-6C++用户指南2004年4月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自动转换为其它类型.
您可以指定是否需要实部、虚部或幅度.
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-8C++用户指南2004年4月15.
7效率complex类的设计主要侧重于效率.
最简单的函数声明为inline,用于消除函数调用的重载.
如果会有所不同,将提供函数的多个重载版本.
例如,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后缀结束.
动态链接共享库较静态链接归档库有多个优势:I可执行文件较小.
I在运行时,代码的有效部分可在程序间共享,这样就可以降低内存使用量.

I库可以在运行时替换,无需重新链接应用程序.
(动态链接共享库的主要机制是使程序能够利用Solaris操作环境的多项改进的功能,而无需重新链接和分发程序.
)I可以使用dlopen()函数调用在运行时装入共享库.
16-2C++用户指南2004年4月但动态库也具有一些缺点:I运行时链接需要消耗执行时间.
I发布使用动态库的程序时可能会要求同时发布该程序所使用的库.
I将共享库移动到其他位置,系统就无法找到该库和执行程序.
(环境变量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文件具有一个函数就可以确保只有这些应用程序所需的符号将与归档链接.
%CC-cfoo.
cc#编译主文件,创建模板对象.
%CC-xar-ofoo.
afoo.
o#将所有对象收集到库中.
第16章生成库16-316.
3生成动态(共享)库动态(共享)库的生成方法与静态(归档)库相同,不同之处是您在命令行上使用的是-G而不是-xar.
您不应该直接使用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-4C++用户指南2004年4月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接口库时,必须提供如何使用该库的相关指令.
I如果C接口的库是使用标准模式下的CC(缺省)生成的,那么在使用该C接口的库时请将-lCrun增加到cc命令行.
I如果C接口的库是使用兼容模式下的CC(-compat)生成的,那么在使用该C接口的库时请将-lC增加到cc命令行.
第16章生成库16-5提供共享的C接口库时,必须在生成库的时候创建对libC或libCrun的依存.
如果共享库具有正确的依存性,您就无需在使用该库时将-lC或-lCrun增加到命令行.
I如果在兼容模式下(-compat)生成C接口库,那么在生成该库时请将-lC增加到CC命令行.
I如果在标准模式下(缺省)生成C接口库,那么在生成该库时请将-lCrun增加到CC命令行.
如果您要删除对C++运行库的任何依存性,就必须在库的源码中使用以下编码规则:I不要使用任何形式的new或delete,除非您提供了自己的相应版本.
I不要使用异常.
I不要使用运行时类型信息(RTTI).
16.
8使用dlopen从C程序访问C++库如果要使用dlopen()从C程序打开某个C++共享库,应确保该共享库对适当的C++运行时库有依存性(对于-compat=4为libC.
so.
5;对于-compat=5为libCrun.
so.
1).
要执行该操作,请在生成共享库时将-compat=4的-lC或-compat=5的-lCrun增加到命令行.
例如:如果共享库使用了异常且不具有对C++运行库的依存性,则C程序可能会出现无规律的行为.
注–使用dlopen()打开共享库时,必须使用RTLD_GLOBAL以使异常生效.
example%CC-G-compat=4.
.
.
-lCexample%CC-G-compat=5.
.
.
-lCrun16-6C++用户指南2004年4月第IV部分附录17-1附录17C++编译器选项本附录详细介绍了在Solaris7和Solaris8操作环境下运行的CC编译器的命令行选项.
所述特性适用于除了说明以外的所有平台;SolarisSPARCPlatformEdition操作环境的唯一特性称为SPARC,而SolarisIntelPlatformEdition操作环境的唯一特性称为IA.
下表显示了典型选项语法格式的示例.
本手册前面的"阅读之前"中列出的排版惯例在这一部分中用于描述单个选项.
圆括号、大括号、括号、管道字符和省略号是选项说明中使用的元字符,而不是选项自身的一部分.
表Q-1选项语法格式示例语法格式示例-option-E-optionvalue-Ipathname-option=value-xunroll=4-optionvalue-ofilename17-2C++用户指南2004年4月Q.
1选项信息的结构为了帮助您查找信息,编译器选项说明被分为以下几个子节.
如果一个选项被其它选项取代或与其它选项一致,就请参阅其它选项的说明以获取完整的详细信息.

表Q-2选项子节子节内容选项定义紧跟在每个选项之后的简短定义.
(该类无标题.
)值如果选项具有一个或多个值,则本节将定义每个值.
缺省如果选项具有主缺省值或辅助缺省值,则在此处进行说明.
如果未指定选项,则主缺省值为有效选项值.
例如,如果未指定-compat,则缺省值为-compat=5.
如果指定了选项但不给定任何值,则辅助缺省值为有效选项值.
例如,如果-compat已指定但没有值,则缺省值为-compat=4.
扩展如果选项具有宏扩展,则将在本节中显示.
示例如果要举例说明选项,则在此处给出所需示例.
交互如果选项与其它选项进行交互,则在此处讨论它们的关系.
警告如果有对选项使用的警告(例如可能产生意外结果的操作),则在此处说明.
另见本节包含关于其它选项或文档更多的参考信息.
"替换为""与.
.
.
相同"如果选项已废弃且已被其它选项替换,则在此处说明替换的选项.
以后的发行版本可能不支持这种方式描述的选项.
如果有两个选项具有相同的含义和目的,则在此处引用首选项.
例如,"与-xO相同"表示-xO为首选项.
附录17C++编译器选项17-3Q.
2选项参考Q.
2.
1-386IA:与-xtarget=386相同.
该选项仅用于向后兼容.
Q.
2.
2-486IA:与-xtarget=486相同.
该选项仅用于向后兼容.
Q.
2.
3-a与-xa相同.
Q.
2.
4-Bbinding指定用于链接的库绑定是否为symbolic、dynamic(共享)或static(非共享).
您可以在命令行上多次使用-B选项.
该选项被传递给链接程序ld.
注–在Solaris7和Solaris8平台上,并非所有的库都可以用作静态库.
17-4C++用户指南2004年4月值binding必须是下列值之一:(在-B和binding值之间不允许有空格.
)缺省如果未指定-B,则假定为-Bdynamic.
交互要静态链接C++缺省库,请使用-staticlib选项.
-Bstatic和-Bdynamic选项会影响缺省提供的库链接.
要确保缺省库是动态链接的,则最后所使用的-B应该是-Bdynamic.
在64位环境下,许多系统库只可以用作共享动态库.
其中包括libm.
so和libc.
so(而不提供libm.
a和libc.
a).
因此,在64位Solaris操作环境下,-Bstatic和-dn可能会产生链接错误.
这些情况下应用程序必须与动态库链接.
示例以下编译器命令链接了libfoo.
a(即使libfoo.
so存在),所有其它库都被动态链接:警告对于包含C++代码的程序,永远不要使用-Bsymbolic,而是要使用链接程序映射文件.
binding的值含义dynamic指定链接编辑器查找liblib.
so(共享)文件,如果未找到,则查找liblib.
a(静态,非共享)文件.
当链接需要共享库绑定时,请使用该选项.
static指定链接编辑器只查找liblib.
a(静态,非共享)文件.
当链接需要非共享库绑定时,请使用该选项.
symbolic如果可能,则强制在共享库中解析符号(即使符号已经在别处定义).
请参阅ld(1)手册页.
example%CCa.
o-Bstatic-lfoo-Bdynamic附录17C++编译器选项17-5使用-Bsymbolic时,在不同模块中的引用可以绑定到被假设为全局对象的不同副本中.
异常机制依赖对地址的比较.
如果您具有某项内容的两个副本,它们的地址就不等同且异常机制可能失败,这是由于异常机制依赖对假设为唯一地址内容的比较.

如果您要分别进行编译和链接,并使用-Bbinding选项,则必须在链接步骤中包含该选项.
另见-nolib,-staticlib,ld(1),第12-10页的第12.
5节"静态链接标准库","静态链接标准库"Q.
2.
5-c仅编译;生成对象.
o文件,但禁止链接.
该选项指定CC驱动程序禁止用ld进行链接,并为每个源文件生成一个.
o文件.
如果只在命令行上指定一个源文件,就可以用-o选项来显式命名目标文件.
示例输入CC-cx.
cc时,生成x.
o目标文件.
而输入CC-cx.
cc-oy.
o时,则生成y.
o目标文件.
警告当编译器为输入文件(.
c,.
i)生成目标代码时,编译器总是在工作目录下生成.
o文件.
如果禁止链接步骤,则不会删除.
o文件.
另见-ofilename,-xeQ.
2.
6-cg{89|92}与-xcg{89|92}相同.
17-6C++用户指南2004年4月Q.
2.
7-compat[={4|5}]设置编译器的主发行版本兼容模式.
该选项控制__SUNPRO_CC_COMPAT和__cplusplus宏.
C++编译器有两个主要模式.
兼容模式接受4.
2编译器所定义的ARM语义和语言.
标准模式接受符合ANSI/ISO标准的构造.
由于ANSI/ISO标准在名称重整、虚函数表布局和其它ABI详细信息中强制进行显著的不兼容的更改,所以这两个模式是互相不兼容的.

这两个模式由以下值中所示的-compat选项进行区分.
值-compat选项可以具有以下值.
缺省如果未指定-compat选项,则假定为-compat=5.
如果仅仅指定了-compat,则假定为-compat=4.
无论-compat如何设置,__SUNPRO_CC都设置为0x550.
交互您无法在兼容模式下(-compat[=4])使用标准库.
不支持对具有下列任何选项的-compat[=4]的使用.
IBsymbolic当库中存在异常时Ifeatures=[no%]strictdestrorderIfeatures=[no%]tmplifeIlibrary=[no%]iostreamIlibrary=[no%]CstdIlibrary=[no%]CrunIlibrary=[no%]rwtools7_stdIxarch=native64,-xarch=generic64,-xarch=v9,-xarch=v9a,or-xarch=v9b值含义-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.
附录17C++编译器选项17-7不支持对具有下列任何选项的-compat=5[=4]的使用.
I+eIfeatures=[no%]arraynewIfeatures=[no%]explicitIfeatures=[no%]namespaceIfeatures=[no%]rttiIlibrary=[no%]complexIlibrary=[no%]libCIvdelx警告在兼容模式下(-compat[=4])创建共享库时,如果库中存在异常,就不要使用-Bsymbolic.
应该捕获的异常可能会丢失.
另见《C++迁移指南》Q.
2.
8+d不扩展C++内联函数.
按照C++语言规则,C++内联函数是一个函数,对于该函数以下语句之一为真.
I该函数的定义使用了inline关键字,I该函数在类定义内部定义(不仅是声明)I该函数是编译器生成的类成员函数按照C++语言规则,编译器可以选择是否将调用实际内联到内联函数.
C++编译器将内联对内联函数的调用,除非:I函数过于复杂,I已选定+d选项,或者I已选定-g选项17-8C++用户指南2004年4月示例缺省情况下,编译器可以在以下代码示例中内联函数f()和memf2().
此外,该类具有编译器可以内联的由编译器生成的缺省构造函数和析构函数.
当您使用+d时,编译器不会内联f()和C::mf2()(即构造函数和析构函数).
交互指定-g调试选项时,该选项自动打开.
-g0调试选项不打开+d.
+d选项不会影响使用-xO4或-xO5时所执行的自动内联.
另见-g0,-gQ.
2.
9-D[]name[=def]将宏符号name定义到预处理程序.
使用该选项与在源码开始位置包括#define指令等效.
您可以使用多个-D选项.
inlineintf(){return0;}//可以被内联classC{intmf1();//不内联,除非稍后出现内联定义intmf2(){return0;}//可以被内联};附录17C++编译器选项17-9值下表显示了预定义的宏.
您可以在如#ifdef这样的预处理程序条件下使用这些值.
表Q-3预定义的宏类型宏名称说明SPARC和IA__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____sunsun请参阅交互.
__SUNPRO_CC=0x550__SUNPRO_CC的值表示编译器的发行版本编号__SUNPRO_CC_COMPAT=4或__SUNPRO_CC_COMPAT=5请参阅第17-6页的第Q.
2.
7节"-compat[={4|5}]"__SVR4__TIME____'uname-s'_'uname-r'在-D__SunOS_5_7和-D__SunOS_5_8中时,uname-s是uname-s的输出,而uname-r是具有无效字符的uname-r的输出,如用下划线替换的句号(.
).
__unixunix请参阅交互.
SPARC__sparc17-10C++用户指南2004年4月如果您不使用=def,则name被定义为1.
交互使用+p,则不定义sun、unix、sparc和i386.
另见-UQ.
2.
10-d{y|n}允许或不允许整个可执行文件的动态库.
该选项被传递给ld.
该选项只能在命令行出现一次.
值缺省如果未指定-d选项,则假定为-dy.
sparc请参阅交互.
SPARCv9__sparcv9只限于64位编译模式IA__i386i386请参阅交互.
UNIX_WCHAR_T值含义-dy在链接编辑器中指定动态链接.
-dn在链接编辑器中指定静态链接.
表Q-3预定义的宏(续下)类型宏名称说明附录17C++编译器选项17-11交互在64位环境下,许多系统库只可以用作共享动态库.
其中包括libm.
so和libc.
so(而不提供libm.
a和libc.
a).
因此,在64位Solaris操作环境下,-Bstatic和-dn可能会产生链接错误.
这些情况下应用程序必须与动态库链接.
另见ld(1),LinkerandLibrariesGuideQ.
2.
11-dalign-dalign等价于-xmemalign=8s.
更多信息请参阅第17-101页的"-xmemalign=ab".
警告如果您用-dalign编译一个程序单元,就要使用-dalign来编辑程序的所有单元,否则会产生意外的结果.
Q.
2.
12-dryrun显示但不编译驱动程序所生成的子命令.
该选项指示驱动程序CC显示但不执行编译驱动程序所构造的子命令.
Q.
2.
13-E在源文件上运行预处理程序但不进行编译.
指示CC驱动程序仅在C++源文件上运行预处理程序,并将结果发送到stdout(标准输出).
不执行任何编译,不生成任何.
o文件.
该选项使预处理程序输入行号信息包括在输出中.
17-12C++用户指南2004年4月示例该选项用于确定预处理程序所进行的更改.
例如,以下程序foo.
cc生成了编码范例Q-2中所示的输出.
警告使用模板时,不支持将该选项的输出作为C++编译器的输入.
另见-PQ.
2.
14+e{0|1}在兼容模式(-compat[=4])下控制虚拟表的生成.
在标准模式下(缺省模式)无效并被忽略.
编码范例Q-1预处理程序示例程序foo.
cc#if__cplusplusintpower(int,int);#endifintmain(){intx;x=power(2,10);}编码范例Q-2使用-E选项的foo.
cc的预处理程序输出example%CC-Efoo.
cc#4"foo.
cc"templateintpower(int,int);intmain(){intx;x=power(2,10);}附录17C++编译器选项17-13值+e选项可以具有以下值.
交互使用该选项进行编译时,请同时使用-features=no%except选项.
否则,编译器会为用于异常处理的内部类型生成虚拟表.
如果模板类具有虚函数,就可能无法确保编译器生成全部所需的虚拟表而不复制这些表.

另见《C++迁移指南》Q.
2.
15-erroff[=t]该命令禁止出现C++编译器警告消息,而不会影响错误消息.
值t是一个由逗号分隔的列表,它由以下一项或多项内容组成:tag,no%tag,%all,%none.
顺序是很重要的;例如%all,no%tag禁止了除tag以外的所有警告消息.
下表列出了-erroff值:值含义0禁止虚拟表的生成并创建对所需虚拟表的外部引用.
1为所有定义的具有虚函数的类创建虚拟表.
表Q-4-erroff值值含义tag禁止由该tag指定的警告消息.
使用-errtags=yes选项可以显示消息的标记.
no%tag启用由该tag指定的警告消息.
%all禁止所有警告消息.
%none启用所有警告消息(缺省).
17-14C++用户指南2004年4月缺省缺省为-erroff=%none.
指定-erroff与指定-erroff=%all相同.
示例例如,-erroff=tag会禁止由该标记指定的警告消息.
另一方面,-erroff=%all,no%tag会禁止除tag指定的消息之外的所有警告消息.
使用-errtags=yes选项可以显示警告消息的标记.
警告使用-erroff选项只可以禁止来自C++编译器前端的警告消息,该警告消息会在使用-errtags选项时显示一个标记.
另见-errtags,-errwarnQ.
2.
16-errtags[=a]显示C++编译器前端每个警告消息的消息标记,使用-erroff选项可以禁止警告消息,使用-errwarn选项则可能产生严重警告.
值和缺省a可以是yes或no.
缺省为-errtags=no.
指定-errtags与指定-errtags=yes相同.
警告来自C++编译器驱动程序和编译系统其它组件的消息没有错误标记,因此无法使用-erroff来禁止,使用-errwarn也不会产生致命错误.
另见-erroff,-errwarn附录17C++编译器选项17-15Q.
2.
17-errwarn[=t]利用-errwarn来使C++编译器在给定警告消息处于失败的状态下退出.
值t是一个由逗号分隔的列表,它由以下一项或多项内容组成:tag,no%tag,%all,%none.
顺序很重要,例如如果出现除tag之外的任何警告,%all,no%tag会使cc从致命错误状态中退出.
下表详细列出了-errwarn值:缺省缺省为-errwarn=%none.
如果单独指定-errwarn,就等价于-errwarn=%all.
警告只有来自C++编译器前端的警告消息可以使用-errwarn选项来使编译器从故障状态中退出,这些警告消息在使用-errtags选项时将显示标记.
因为编译器错误检查的改进和功能的增加,C++编译器生成的警告消息在不同发行版本中各有不同.
使用-errwarn=%all进行编译而不会产生错误的代码,在编译器下一个发行版本中编译时也可能出现错误.
另见-erroff,-errtags表Q-5-errwarn值值含义tag如果该tag指定的消息以警告消息的形式出现,就会使CC从致命错误状态中退出.
如果未发出tag,则不会产生这种情况.
no%tag如果tag指定的消息只以警告消息的形式出现,则阻止CC从致命错误状态中退出.
如果tag指定的消息未出现,则不会产生任何影响.
为了避免在发生警告消息时导致cc从致命错误状态中退出,就要使用该选项来还原以前用tag或%all指定的警告消息.
%all如果发生任何警告消息,就会使CC从致命错误状态中退出.
%all可以后跟no%tag以避免该行为的特定警告消息.
%none如果有任何警告消息发出,阻止CC从任何致命错误状态中退出.
17-16C++用户指南2004年4月Q.
2.
18-fast选择某些选项来优化执行速度.
该选项是一个宏,它选择用于在编译代码的机器上优化执行速度的编译选项组合.

扩展该选项通过扩展到以下编译选项,为大量应用程序提供了几乎最高的性能.

交互-fast宏扩展到可能影响其它指定选项的编译选项中.
例如,在以下命令中,-fast宏的扩展包括了将-xarch还原为32位架构选项的-xtarget=native.
错误:正确:表Q-6-fast扩展选项SPARCIA-fnsXX-fsimple=2X--ftrap=%noneXX-nofstore-X-xarchXX-xlibmilXX-xlibmoptXX-xmemalignX--xO5XX-xtarget=nativeXX-xbuiltin=%allXXexample%CC-xarch=v9-fasttest.
ccexample%CC-fast-xarch=v9test.
cc附录17C++编译器选项17-17查看每个选项的描述以确定可能的交互操作.
代码生成选项、优化级别、内建函数的优化和内联模板文件的使用可以用后续选项来覆盖(请参阅示例).
指定的优化级别将覆盖以前所设置的优化级别.
-fast选项包括-fns-ftrap=%none;即,该选项关闭了所有捕获.
示例以下编译器命令生成了-xO3的优化级别.
以下编译器命令产生了-xO5的优化级别.
警告如果在不同的步骤中编译和链接,-fast选项就必须出现在编译命令和链接命令中.
-fast选项所编译的代码不可移植.
例如,在UltraSPARCII系统中无法执行在UltraSPARCIII系统中用以下命令生成的二进制文件.
不要将该选项用于依赖IEEE标准浮点运算的程序,否则可能会产生不同的数字结果、过早的程序终止或无法预料的SIGFPE信号.
在以前的SPARC发行版本中,-fast宏扩展到了-fsimple=1.
而现在扩展到-fsimple=2.
在以前的发行版本中,-fast宏扩展到了-xO4.
而现在扩展到-xO5.
注–在以前的SPARC发行版本中,-fast宏选项包括了-fnonstd,而现在的版本则不包括.
非标准浮点模式不再用-fast初始化.
请参阅《数值计算指南》,ieee_sun(3M).
example%CC-fast-xO3example%CC-xO3-fastexample%CC-fasttest.
cc17-18C++用户指南2004年4月另见-fns、-fsimple、-ftrap=%none、-xlibmil,-nofstore、-xO5、-xlibmopt、-xtarget=nativeQ.
2.
19-features=a[,a.
.
.
]启用/禁用在逗号分隔的列表中命名的各种C++语言功能.
值在兼容模式(-compat[=4])和标准模式(缺省模式)下a都可以具有以下值:表Q-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.
附录17C++编译器选项17-19在标准模式(缺省模式)下,a可以具有以下附加值:[no%]mutable[不]识别关键字mutable.
在兼容模式下缺省为no%mutable,在标准模式下缺省为mutable.
[no%]split_init[不]将非局部静态对象的初始化函数放入个别函数中.
使用-features=no%split_init时,编译器将所有初始化函数放入一个函数中.
使用-features=no%split_init在可能占用编译时间的情况下将代码大小最小化.
缺省为split_init.
[no%]transitions[不]允许使用ARM语言构造,该构造会在标准C++下产生问题,且可能使程序无法按预期运行或不能使用以后的编译器进行编译.
使用-features=no%transitions时,编译器会将这种情况视为错误.
在标准模式下使用-features=transitions时,编译器会发出关于这些构造的警告,而不发出错误消息.
兼容模式(-compat[=4])下使用-features=transitions时,编译器仅在指定+w或+w2的情况下才显示关于这些构造的警告.
以下构造被认为是转换错误:在使用模板之后再重定义模板,忽略在模板定义时所需的typename指令,隐式声明类型int.
在以后的发行版本中可能会更改转换错误的集合.
缺省为transitions.
%none关闭指定模式中可以关闭的所有功能.
表Q-8仅用于标准模式的-features值a的值含义[no%]strictdestrorder[不]遵循由C++标准指定的要求,该要求关于具有静态存储持续时间对象的析构顺序.
缺省为strictdestrorder.
[no%]tmplife[不]清除由位于全表达式结尾处的表达式(在ANSI/ISOC++标准中定义)创建的临时对象.
(-features=no%tmplife生效时,多数临时对象会在块的结尾处清除.
)缺省为no%tmplife.
表Q-7兼容模式和标准模式的-features值(续下)a的值含义17-20C++用户指南2004年4月在兼容模式(-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,则做出以下假定:I兼容模式(-compat[=4])I标准模式(缺省模式)表Q-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.
-features=%none,anachronisms,except,split_init,transitions-features=%all,no%iddollar,no%extensions附录17C++编译器选项17-21交互该选项会累积而不覆盖.
在标准模式(缺省)中以下选项与标准库和头文件不兼容:Ino%boolIno%exceptIno%mutableIno%explicit在兼容模式(-compat[=4])下,-features=transitions选项无效,除非您指定了+w选项或+w2选项.
警告使用-features=tmplife选项时,程序的行为可能更改.
测试程序是否可以使用-features=tmplife选项是测试程序可移植性的一种方法.
缺省情况下,编译器假定为-features=split_init.
如果使用-features=%none选项来关闭其它功能,就会发现需要通过使用-features=%none,split_init将初始化函数的分离部分转换到独立的函数中.
另见第4章和《C++迁移指南》17-22C++用户指南2004年4月Q.
2.
20-filt[=filter[,filter.
.
.
]]控制编译器通常应用于链接程序和编译器错误消息的过滤.
值filter必须是下列值之一:缺省如果未指定-filt选项或指定没有任何值的-filt,那么编译器假定-filt=%all.
示例以下示例显示了使用-filt选项编译该代码的效果.
表Q-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;}附录17C++编译器选项17-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.
17-24C++用户指南2004年4月交互当您指定no%names时,无论是returns还是no%returns都是无效的.
也就是说,以下选项是相同的:I-filt=no%namesI-filt=no%names,no%returnsI-filt=no%names,returnsQ.
2.
21-flags与-xhelp=flags相同.
Q.
2.
22-fnonstd使硬件自陷可用于浮点溢出,除以零,并可用于无效运算异常.
产生的结果被转换为SIGFPE信号,如果程序没有SIGFPE处理程序,它就会终止并转储内存(除非将核心转储大小限制到零).
SPARC:此外,-fnonstd还选择SPARC非标准浮点.
缺省如果未指定-fnonstd,则IEEE754浮点算术异常不会终止程序,且下溢是逐步.
扩展IA:-fnonstd扩展到-ftrap=common.
SPARC:-fnonstd扩展到-fns-ftrap=common.
另见-fns,-ftrap=common,《数值计算指南》.
附录17C++编译器选项17-25Q.
2.
23-fns[={yes|no}]SPARC:启用/禁用SPARC的非标准浮点模式.
-fns=yes(或-fns)会在程序开始执行时启用非标准浮点模式.
该选项提供了一种切换非标准或标准浮点模式的方法,后跟包括-fns的某些其它宏选项(如-fast).
(见"示例".
)在某些SPARC设备上,非标准浮点模式会禁用"逐步下溢",这会导致微小的结果被刷新为零而不是产生次正规数,还会导致低于正常的操作数被默置为零.

在不支持硬件逐步下溢和低于正常的数的SPARC设备上,-fns=yes(或-fns)可以显著提高某些程序的性能.
值-fns选项可以具有以下值.
缺省如果未指定-fns,则不自动启用非标准浮点模式.
标准IEEE754浮点计算发生(即逐步下溢).
如果仅指定了-fns,则假定-fns=yes.
示例在以下示例中,-fast扩展到了多个选项,其中一个是-fns=yes,即选择非标准浮点模式.
随后-fns=no选项覆盖初始设置,并选择浮点模式.
表Q-11-fns值值含义yes选择非标准浮点模式no选择标准浮点模式example%CCfoo.
cc-fast-fns=no17-26C++用户指南2004年4月警告非标准模式启动时,浮点运算可以产生不符合IEEE754标准要求的结果.
如果先使用-fns选项编译一个例程,就要使用-fns选项来编译程序的所有例程;否则,就可能获得无法预料的结果.
该选项仅在SPARC设备上有效,并且仅在编译主程序时才能有效使用.
在IA设备上,该选项被忽略.
在程序中出现通常由IEEE浮点自陷处理程序管理的浮点错误时,使用ns=yes(或-fns)选项可能会生成以下消息:另见《数值计算指南》,ieee_sun(3M)Q.
2.
24-fprecision=pIA:设置非缺省的浮点精度模式.
-fprecision选项设置"浮点控制字"中的取整精度模式位.
这些位控制基本算术运算(加、减、乘、除和平方根)结果的取整精度.
值p必须是下列值之一:如果p为single或double,则该选项会使取整精度模式在程序开始执行时分别设置为single或double精度.
如果p是extended或未使用-fprecision选项,则取整精度模式会保留为extended精度.
表Q-12-fprecision值p的值含义single取整到IEEE单精度值.
double取整到IEEE双精度值.
extended取整到最大可用精度.
附录17C++编译器选项17-27single精度取整模式会将结果取整到24个有效位,而double精度取整模式会将结果取整到53个有效位.
在缺省的extended精度模式下,结果被取整到64个有效位.
该模式只控制在寄存器中结果的取整精度,而不影响范围.
寄存器中所有的结果都使用了各种已扩展的双精度格式来取整.
不过,存储在内存中的结果既取整到目标格式的范围也取整到目标格式的精度.
float类型的名义精度为single.
longdouble类型的名义精度为extended.
缺省未指定-fprecision选项时,缺省的取整精度模式为extended.
警告该选项仅对IA设备有效,且仅在编译主程序时使用.
在SPARC设备上,该选项被忽略.
Q.
2.
25-fround=r启动时将IEEE取整模式设置为有效.
该选项将IEEE754取整模式设置为:I编译器可以将其用于计算常量表达式I程序初始化期间在运行时建立该含义与ieee_flags子例程的含义相同,可用于更改运行时的模式.
值r必须是下列值之一:表Q-13-fround值r的值含义nearest取整到最接近的数字并转变为偶数.
tozero取整到零.
negative取整到负无穷大.
positive取整到正无穷大.
17-28C++用户指南2004年4月缺省未指定-fround选项时,缺省的取整模式为-fround=nearest.
警告如果先使用-fround=r编译一个例程,就还要使用相同的-fround=r选项来编译程序的所有例程;否则就会获得无法预料的结果.
只有编译主程序时该选项才有效.
Q.
2.
26-fsimple[=n]选择浮点优化首选项.
该选项允许优化器简化关于浮点运算的假定.
值如果存在n,则必须是0、1或2.
表Q-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的值为常量值.
附录17C++编译器选项17-29缺省如果未指定-fsimple,则编译器使用-fsimple=0.
如果指定了-fsimple但未给定n任何值,则编译器使用-fsimple=1.
交互-fast暗含了-fsimple=2.
警告该选项可以破坏IEEE754的符合性.
另见-fastQ.
2.
27-fstoreIA:在以下值为真时,该选项使编译器将浮点表达式或函数的值转换为赋值左侧的类型,而不是将该值保留在寄存器中:I将表达式或函数分配到变量.
I表达式被转换为较短的浮点类型.
要关闭该选项,请使用-nofstore选项.
警告由于舍入和截断,结果可能会与寄存器值所生成的结果不同.
另见-nofstore17-30C++用户指南2004年4月Q.
2.
28-ftrap=t[,t.
.
.
]设置启动时生效的IEEE自陷模式.
该选项设置在程序初始化时所建立的IEEE754自陷模式,但不安装SIGFPE处理程序.
您可以使用ieee_handler启用自陷,并同时安装SIGFPE处理程序.
使用多个值时,会从左至右依次处理列表.
值t可以是下列值之一:注意,选项的[no%]形式只用于修改%all和common值的含义,且必须用于其中的一个值,如以下示例所示.
选项自身的[no%]形式不会显式导致禁用特定的自陷.
要启用IEEE自陷,推荐设置为-ftrap=common.
缺省如果未指定-ftrap,则假定-ftrap=%none值.
(未自动启用自陷.
)示例给定一个或多个词汇时,会从左至右依次处理该列表,此时-ftrap=%all,no%inexact意味着设置除不精确自陷以外的所有自陷.
表Q-15-ftrap值t的值含义[no%]division[不]在除以零时自陷.
[no%]inexact[不]在结果不精确时自陷.
[no%]invalid[不]在无效操作上自陷.
[no%]overflow[不]在溢出上自陷.
[no%]underflow[不]在下溢上自陷.
%all出现以上所有情况时自陷.
%none不在以上任何内容中自陷.
common在无效、除以零和溢出时自陷.
附录17C++编译器选项17-31交互可以在运行时使用ieee_handler(3M)更改该模式.
警告如果先使用-ftrap=t编译一个例程,就还要使用相同的-ftrap=t选项来编译程序的所有例程;否则就会获得无法预料的结果.
使用-ftrap=inexact自陷时要小心操作.
只要浮点值不能精确表示,就会使用-ftrap=inexact产生自陷.
例如,以下语句就会产生这种情况:只有编译主程序时该选项才有效.
请小心使用该选项.
如果您希望启用IEEE自陷,请使用-ftrap=common.
另见ieee_handler(3M)手册页Q.
2.
29-G生成动态共享库来取代可执行文件.
缺省情况下,在命令行指定的所有源文件使用-Kpic来编译.
生成使用模板的共享库时,多数情况下有必要将这些模板函数包括在共享库中,而这些函数已在模板数据库中实例化.
使用该选项可以在需要时将这些模板自动增加到共享库中.

交互如果未指定-c(仅编译选项),以下选项就会被传递给ld.
I-dyI-GI-Rx=1.
0/3.
0;17-32C++用户指南2004年4月警告不要使用ld-G来生成共享库,而要使用CC-G.
CC驱动程序自动将多个选项传递给C++所需的ld中.
使用-G选项时,编译器不将任何缺省l选项传递给-ld选项.
如果您要使共享库具有对另一共享库的依存性,就必须在命令行上传递必需的-l选项.
例如,如果您要使共享库具有对libCrun的依存性,就必须在命令行上传递-lCrun.
另见-dy、-Kpic、-xcode=pic13、-xildoff、-ztext、ld(1)手册页第16-3页的第16.
3节"生成动态(共享)库".
Q.
2.
30-g产生了使用dbx(1)或调试程序进行调试和使用性能分析器analyzer(1)进行分析的附加符号表信息.
指示编译器和链接程序准备进行调试和性能分析的文件或程序.
其任务包括:I在目标文件和可执行文件的符号表中生成stabs详细信息.
I生成某些"帮助函数",调试程序可以调用这些函数来实现自身某些特性.
I禁用函数的内联生成.
I禁用优化的某些级别.
交互如果与-xOlevel(或其等价选项,如-O)一起使用该选项,那么将会获得有限的调试信息.
更多信息请参阅第17-106页的第Q.
2.
141节"-xOlevel".
如果您所用选项的优化级别为-xO3或更低,编译器就会提供已基本全部优化的最多的符号信息.
尾部调用优化和后端内联被禁用.
如果您所用选项的优化级别为-xO4或更高,编译器就会提供全部优化的最多的符号信息.
指定该选项时,+d选项被自动指定.
该选项将-xildon设置为缺省的递增链接程序选项,以加速编译-编辑-调试周期.
附录17C++编译器选项17-33该选项调用ild而不调用ld,除非满足以下任何一个条件:I-G选项出现I-xildoff选项出现I任何源文件都在命令行上命名要使用性能分析器的所有功能,请使用-g选项进行编译.
某些性能分析特性不需要-g时,您必须使用-g进行编译,以查看已注释的源码、某些函数级别信息和编译器注释消息.
更多信息,请参阅analyzer(1)手册页和《程序性能分析工具》中的"为数据收集和分析编译程序".
使用-g生成的注释消息描述了编译器在编译程序时进行的优化和转换.
使用er_src(1)命令来显示与源代码交叉的消息.
警告如果在不同的步骤中编译和链接程序,那么将-g选项包括在一步骤中并将该选项从其它步骤中排除不会影响程序的正确性,但这样会影响调试程序的能力.
没有使用-g(或-g0)编译但使用-g(或-g0)链接的任何模块将不能正常调试.
注意,包含函数main的模块通常需要使用-g选项(或-g0选项)来编译才可用于调试.
另见+d、-g0、-xildoff、-xildon、-xs、analyzer(1)手册页,er_src(1)手册页,ld(1)手册页,使用dbx(关于stab的详细信息)调试程序,《程序性能分析工具》.
Q.
2.
31-g0为调试而进行编译和链接,但不禁用内联.
除+d被禁用,该选项与-g相同.
另见+d、-g、-xildon,《使用dbx调试程序》Q.
2.
32-H打印包含文件的路径名称.
在标准错误输出(stderr)中,该选项打印当前编译中包含的每个#include文件的路径名称(每行一个名称).
17-34C++用户指南2004年4月Q.
2.
33-h[]name将名称name分配到生成的动态共享库.
这是一个加载器选项,传递给ld.
通常,-h后的名称应该与-o后的名称完全相同.
在-h和name之间的空格是可选的.
编译时的加载器将指定名称分配到正在创建的共享动态库中,并将该名称作为库的内部名称记录在库文件中.
如果没有-hname选项,在库文件中就没有记录内部名称.
每个可执行文件都具有所需的共享库文件列表.
当运行时链接程序将库链接到可执行文件中时,链接程序将内部名称从库复制到所需共享库文件的列表中.
如果没有共享文件的内部名称,链接程序就复制共享库文件的路径.
示例Q.
2.
34-help与-xhelp=flags相同.
Q.
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目录中example%CC-G-olibx.
so.
1-hlibx.
so.
1a.
ob.
oc.
o附录17C++编译器选项17-353.
在/usr/include目录中注–如果拼写与标准头文件的名称相匹配,也可参阅第12-14页的第12.
7.
5节"标准头文件实现".
交互-I-选项使您能够覆盖缺省的搜索规则.
如果指定了-library=no%Cstd,那么编译器在其搜索路径中就不包括编译器提供的与C++标准库相关的头文件.
请参阅第12-12页的第12.
7节"替换C++标准库".
如果未使用-ptipath,编译器就会在-Ipathname中查找模板文件.
请使用-Ipathname而不要使用-ptipath.
该选项会累积而不覆盖.
另见-I-Q.
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-14页的第12.
7.
5节"标准头文件实现".
17-36C++用户指南2004年4月示例以下示例显示了编译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附录17C++编译器选项17-37下一条命令显示了-I-选项的结果.
编译器处理#include"foo.
h"形式的语句时,并不首先在包含的目录中查找.
相反,编译器按照目录在命令行上出现的顺序,搜索通过-I选项命名的目录.
在inc/a.
h中处理#include"c.
h"语句时,编译器包括了.
/c.
h头文件,而没有包括inc/c.
h头文件.
交互-I-出现在命令行时,编译器不再搜索当前目录,除非该目录显式列于-I指令中.
该结果甚至还适用于#include"foo.
h"形式的包括语句.
警告只有命令行上的第一个-I-会引起描述的行为.
Q.
2.
37-i告知链接程序ld(1)忽略任何LD_LIBRARY_PATH设置.
Q.
2.
38-inline与-xinline相同.
Q.
2.
39-instances=a控制模板实例的放置和链接.
example%CC-c-I.
-I--Iinc-Hprog.
ccinc/a.
h.
/c.
hinc/b.
hinc/c.
h.
/c.
h17-38C++用户指南2004年4月值a必须是下列值之一:缺省如果未指定-instances,则假定-instances=global.
另见第7-2页的第7.
2.
4节"模板实例的放置和链接".
Q.
2.
40-instlib=filename使用该选项以避免在库(共享或静态)和当前对象中生成重复的模板实例.
一般来说,如果程序与函数库共享大量的实例,则可以试试-instlib=filename选项,您会发现编译时间会减少.
值:使用filename参数以指定包含现有模块实例的库(已知的).
filename参数必须包含正斜杠"/"字符.
与当前目录相关的路径要使用点斜杠".
/".
表Q-16-instances值a的值含义explicit将显式实例化的实例放置到当前目标文件中并赋予全局链接.
不生成其它任何所需实例.
extern将全部所需示例放置到模块系统信息库并赋予全局链接.
(如果系统信息库中的实例过期,就会被重新实例化.
)global将全部所需的实例放置到当前目标文件中并赋予全局链接.
semiexplicit将显式实例化的实例放置到当前目标文件中并赋予全局链接.
将显式实例所需的全部实例放置到当前目标文件中并赋予全局链接.
不生成其它任何所需实例.
static将全部所需的实例放置到当前目标文件中并赋予静态链接.
附录17C++编译器选项17-39缺省:-instlib=filename选项不是缺省选项,只有在指定该选项之后才能使用.
该选项可被多次指定和累积.
示例:假定libfoo.
a和libbar.
so库实例化与源文件a.
cc共享的大量模板实例.
增加-instlib=filename并指定库可以通过避免冗余,帮助减少编译时间.
example%CC-c-instlib=.
/libfoo.
a-instlib=.
/libbar.
soa.
cc交互:使用-g进行编译时,如果用-instlib=filename指定的库没有用-g来编译,那么这些模板实例是不可调试的.
解决方法是在使用-g时避免-instlib=filename.
未搜索-L路径以查找命名的库.
警告如果使用-instlib指定库,就必须与该库链接.
另见:-template,-instances,-ptiQ.
2.
41-KPICSPARC:与-xcode=pic32相同.
IA:与-Kpic相同.
生成共享库时使用该选项编译源文件.
对全局数据的每个引用都生成为全局偏移表中指针的非关联化.
每个函数调用都通过过程链接表在pc相对地址模式中生成.
17-40C++用户指南2004年4月Q.
2.
42-KpicSPARC:与-xcode=pic13相同.
IA:使用与位置无关的代码进行编译.
生成共享库时使用该选项编译源文件.
对全局数据的每个引用都生成为全局偏移表中指针的非关联化.
每个函数调用都通过过程链接表在pc相对地址模式中生成.
Q.
2.
43-keeptmp保留编译时创建的临时文件.
加上-verbose=diags,该选项就可用于调试.
另见-v,-verboseQ.
2.
44-Lpath将path增加到目录列表以搜索库.
该选项被传递给ld.
path命名的目录先于编译器提供的目录搜索.
交互该选项会累积而不覆盖.
Q.
2.
45-llib将库liblib.
a或liblib.
so增加到搜索库的链接程序列表.
该选项被传递给ld.
正常的库具有诸如liblib.
a或liblib.
so的名称,其中lib和.
a或.
so部分是必需的.
应该使用该选项指定lib部分.
将尽可能多的库输入到在单一命令行上,这些库按照-Ldir指定的顺序搜索.
请在目标文件名之后使用该选项.
附录17C++编译器选项17-41交互该选项会累积而不覆盖.
在源码和对象的列表之后放入-lx可以确保按照正确顺序搜索这些库.
警告要确保正确的库链接顺序,必须使用-mt而不是-lthread与libthread链接.
如果正使用POSIX线程,就必须用-mt和-lpthread选项链接.
由于libCrun(标准模式)和libC(兼容模式)需要多线程应用程序的libthread,所以-mt选项是必须的.
另见-Ldir、-mt、第12章和Tools.
h++ClassLibraryReferenceQ.
2.
46-libmieee与-xlibmieee相同.
Q.
2.
47-libmil与-xlibmil相同.
Q.
2.
48-library=l[,l.
.
.
]将指定的CC提供的库放入编译和链接中.
17-42C++用户指南2004年4月值对于兼容模式(-compat[=4]),l必须是下列值之一.
在标准模式(缺省模式)下,l必须是下列值之一:表Q-17用于兼容模式的-library值l的值含义[no%]f77已废弃.
不要使用.
Use-xlang=f77.
[no%]f90已废弃.
不要使用.
使用-xlang=f90.
[no%]f95已废弃.
不要使用.
使用-xlang=f95.
[no%]rwtools7[不]使用传统iostreamsTools.
h++版本7.
[no%]rwtools7_dbg[不]使用可调试的Tools.
h++版本7.
[no%]complex[不]使用复数运算的libcomplex.
[no%]interval已废弃.
不要使用.
使用-xia.
[no%]libC[不]使用libCC++支持库.
[no%]gc[不]使用libgc垃圾收集.
[no%]sunperfSPARC:[不]使用SunPerformanceLibrary%all已废弃.
-library=%all与指定-library=f77,f90,rwtools7,complex,interval,gc相同.
注意,除非libC库使用-library=no%libC特别排除,否则始终包括该库.
关于附加信息,请参阅警告一节.
%none仅使用libCC++库.
表Q-18用于标准模式的-library值l的值含义[no%]f77已废弃.
不要使用.
Use-xlang=f77.
[no%]f90已废弃.
不要使用.
使用-xlang=f90.
[no%]f95已废弃.
不要使用.
使用-xlang=f95.
[no%]rwtools7[不]使用传统iostreamsTools.
h++版本7.
[no%]rwtools7_dbg[不]使用可调试的Tools.
h++版本7.
[no%]rwtools7_std[不]使用标准iostreamsTools.
h++版本7.
[no%]rwtools7_std_dbg[不]使用可调试的标准iostreamsTools.
h++7.
[no%]interval已废弃.
不要使用.
使用-xia.
[no%]iostream[不]使用libiostream传统iostreams库.
附录17C++编译器选项17-43缺省I兼容模式(-compat[=4])I如果未指定-library,则假定为-library=%none.
I除非libC库使用-library=no%libC被特别排除,否则始终包括该库.
I标准模式(缺省模式)I如果未指定-library,则假定为-library=%none,Cstd.
I除非libCstd库使用-library=%none、-library=no%Cstd或-library=stlport4被特别排除,否则始终包括该库.
I除非libCrun库使用-library=no%Crun被特别排除,否则始终包括该库.
示例要在没有任何C++库(除libCrun)的标准模式下进行链接,请使用:要在标准模式下包括传统iostreamsRogueWavetools.
h++库,请使用:[no%]Cstd[不]使用libCstdC++标准库.
[不]包括编译器提供的C++标准库头文件.
[no%]Crun[不]使用libCrunC++运行库.
[no%]gc[不]使用libgc垃圾收集.
[no%]stlport4[不]使用STLport的标准库实现版本4.
5.
3代替缺省的libCstd.
关于使用STLport实现的更多信息,请参阅第13-14页的"STLport".
[no%]stlport4_dbg[不]使用STLport可调试的库.
[no%]sunperfSPARC:[不]使用SunPerformanceLibrary.
%all已废弃.
-library=%all与指定-library=f77,f90,rwtools7,Cstd相同.
注意,除非libCrun库使用-library=no%Crun被特别排除,否则始终包括该库.
关于附加信息,请参阅警告一节.
%none仅使用libCrunC++库.
example%CC-library=%noneexample%CC-library=rwtools7,iostream表Q-18用于标准模式的-library值(续下)l的值含义17-44C++用户指南2004年4月要在标准模式下包括标准iostreamsRogueWavetools.
h++库,请使用:要在兼容模式下包括传统iostreamsRogueWavetools.
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++库选项的有效和无效的使用.
example%CC-library=rwtools7_stdexample%CC-compat-library=rwtools7%CC-compat-library=rwtoolsfoo.
ccstructS{voidimf(){}staticvoidsmf(){}};templateclassS;intmain(){}example%17-60C++用户指南2004年4月指定-template=geninlinefuncs时,即使在该程序中不调用S的两个成员函数,也会在目标文件中生成这两个函数.
另见第7-2页的"整个类实例化",第7-7页的"模板定义搜索"Q.
2.
90-time与-xtime相同.
Q.
2.
91-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_]附录17C++编译器选项17-61示例以下命令取消了预定义符号__sun的定义.
foo.
cc中的预处理程序语句(例如#ifdef(__sun))会判断出该符号是未定义的.
交互您可以在命令行上指定多个-U选项.
所有的-U选项都在任何-D选项出现之后处理.
也就是说,如果在命令行上为-D和-U指定了相同的name,则name是未定义的,这与选项出现的顺序无关.
另见-DQ.
2.
92-unroll=n与-xunroll=n相同.
Q.
2.
93-V与-verbose=version相同.
Q.
2.
94-v与-verbose=diags相同.
Q.
2.
95-vdelx仅兼容模式(-compat[=4]):对于使用delete[]的表达式,该选项生成对运行时库函数_vector_deletex_的调用,而不生成对_vector_delete_的调用.
函数_vector_delete_具有两个参数:要删除的指针和每个数组元素的大小.
example%CC-U__sunfoo.
cc17-62C++用户指南2004年4月函数_vector_deletex_(唯一的不同之处在于具有第三个参数用于类的析构函数地址)与_vector_delete_的行为相同.
第三个参数不用于该函数,而是供第三方供应商使用.
缺省该编译器为使用delete[]的表达式生成对_vector_delete_的调用.
警告这是在以后的发行版本中要删除的废弃选项.
除非您已从第三方供应商购买了某些软件且供应商推荐使用该选项,否则请不要使用该选项.
Q.
2.
96-verbose=v[,v…]控制编译器冗长.
值v必须是下列值之一:缺省如果未指定-verbose,则假定为-verbose=%none.
表Q-23-verbose值v的值含义[no%]diags[不]为每个编译传递打印命令行.
[no%]template[不]打开模板实例化verbose模式(有时称为"验证"模式).
verbose模式显示编译过程中实例化的每个阶段.
[no%]version[不]指定CC驱动程序打印调用程序的名称和版本编号.
%all调用以上所有内容.
%none-verbose=%none与-verbose=no%template,no%diags,no%version相同.
附录17C++编译器选项17-63交互该选项会累积而不覆盖.
Q.
2.
97+w标识可能产生意外结果的代码.
如果函数过大而无法内联或声明的程序元素未被使用,那么+w选项不再生成警告.
该警告不指定源码中的真正问题,因此不适合某些开发环境.
将这些警告从+w删除就可以在这些环境下更主动的使用+w.
这些警告仍然可以与+w2选项一起使用.
该选项生成如下关于有问题构造的其它警告:I不可移植I可能出错I低效缺省如果未指定+w,则编译器警告构造极可能出现问题.
交互某些C++标准头文件在使用+w编译时会产生警告.
另见-w,+w2Q.
2.
98+w2发出由+w提供的所有警告,以及关于技术违规的附加警告.
这类技术违规可能是无害的,但可能会降低系统的最大可移植性.
+w2选项不再发出关于依赖于实现系统头文件中构造的警告.
因为系统头文件是实现,所以发出警告是不合适的.
从+w2删除这些警告可以更主动地使用该选项.
警告某些Solaris和C++标准头文件在使用+w2编译时会产生警告.
17-64C++用户指南2004年4月另见+wQ.
2.
99-w禁止大多数警告消息.
该选项使编译器不打印警告消息.
不过某些警告(尤其是严重的记时错误)不能被禁止.
另见+wQ.
2.
100-Xm与-features=iddollar相同.
Q.
2.
101-xa为文件配置生成代码.
如果在编译时进行设置,则TCOVDIR环境变量会指定覆盖(.
d)文件所在的目录如果该变量未设置,则覆盖(.
d)文件仍与source文件保存在同一目录中.
使用该选项是为了向后兼容旧的覆盖文件.
交互-xprofile=tcov选项和-xa选项在单一可执行文件中兼容.
也就是说,您可以链接程序,其中包含了用-xprofile=tcov编译过的某些文件和用-xa编译的其它文件.
您不能同时用这两个选项来编译单一文件.
-xa选项与-g不兼容.
警告如果在不同的步骤中编译和链接且使用-xa编译,就要确保也使用--xa进行链接,否则会产生无法预料的结果.
附录17C++编译器选项17-65另见-xprofile=tcov、tcov(1)手册页,《程序性能分析工具》.
Q.
2.
102-xalias_level[=n](SPARC)指定以下命令时,C++编译器可以执行基于类型的别名分析和优化:I-xalias_level[=n]其中n是any、simple或compatible.
I-xalias_level=any在此分析级别上,编译器假定任何类型都可以为其它类型起别名.
不过尽管只是假定,但还是可以执行某些优化.
I-xalias_level=simple编译器假定简单的类型没有别名.
具体来说就是具有动态类型的存储对象,这些类型是以下简单类型之一:只能通过以下类型的左值访问:I对象的动态类型I对象动态类型的constant或volatile限定版本,与对象动态类型相对应的带符号或不带符号的类型I与对象动态类型的constant或volatile限定版本相对应的带符号或不带符号的类型I在其成员(包括递归的子集成员或包含的联合)中包括上述类型的聚集或联合类型Ichar或unsignedchartypeI-xalias_level=compatible编译器假定布局不兼容类型没有别名.
存储对象只能通过以下类型的左值访问:I对象的动态类型I对象动态类型的constant或volatile限定版本,与对象动态类型相对应的带符号或不带符号的类型charshortintlongintfloatsignedcharunsignedshortintunsignedlongintdoubleunsignedcharintlonglongintlongdoublewchar_tunsignedintunsignedlonglongint枚举类型数据指针类型函数指针类型数据成员指针类型函数成员指针类型17-66C++用户指南2004年4月I与对象动态类型的constant或volatile限定版本相对应的带符号或不带符号的类型I在其成员(包括递归的子集成员或包含的联合)中包括上述类型的聚集或联合类型I对象动态类型的基类类型(可能用constant或volatile限定)Ichar或unsignedchartype.
编译器假定所有引用的类型都与相应存储对象的动态类型是布局兼容的.
两种类型在以下情况下是布局兼容的:I如果两个类型相同,则这两个类型就是布局兼容的类型.
I如果两个类型仅在constant或volatile限定中不同,则这两个函数是布局兼容的类型.
I每个存在的有符号整数类型对应(但是不相同)一个无符号整数类型.
这些对应的类型是布局兼容的.
I如果两个枚举类型具有相同的基础类型,则它们是布局兼容的.
I如果两个PlainOldData(POD)结构类型具有相同数量的成员,并且对应的成员(按顺序)具有布局兼容的类型,那么这两个结构类型是布局兼容的.
I如果两个POD联合类型具有相同数量的成员,并且对应的成员(按顺序)具有布局兼容的类型,那么这两个联合类型是布局兼容的.
在某些情况下具有存储对象动态类型的引用可能是非布局兼容的:I如果POD联合包含了两个或两个以上共享通用初始序列的POD结构,且POD联合对象当前包含了其中一个POD结构,就可以检查任何POD结构的通用初始部分.
对包含一个或多个初始成员的序列来说,如果相应成员具有布局兼容类型(适用于位字段)和相同宽度,则两个POD结构共享一个通用初始序列.
I指向POD结构对象的指针(使用reinterpret_cast适当转换)将指向该结构的初始成员,而如果该成员是位字段则指向该结构所在的单元.
缺省如果未指定-xalias_level,则编译器将选项设置为-xalias_level=any.
如果指定了-xalias_level但未提供任何值,则编译器将选项设置为-xalias_level=compatible.
交互编译器在-xO2及低于它的优化级别下不执行基于类型的别名分析.
附录17C++编译器选项17-67警告如果正使用reinterpret_cast或等价的旧式类型转换,那么程序就可能违反分析的假定.
此外,联合类型也违反了分析的假定,如以下示例所示.
Q.
2.
103-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.
o17-68C++用户指南2004年4月另见ar(1),第16章Q.
2.
104-xarch=isa指定目标指令集架构(ISA).
该选项将编译器生成的代码限制到特定指令集架构的指令.
该选项不保证使用任何特定目标的指令.
不过,使用该选项会影响二进制程序的可移植性.
值对于SPARC平台:表Q-24给出了SPARC平台上每个-xarch关键字的详细信息.
表Q-24SPARC平台的-xarch值isa的值含义generic在多数系统上生成高性能的32位对象二进制文件.
这是缺省行为.
该选项在多数处理器上使用高性能的最佳指令集,同时不降低处理器的主要性能.

如果需要,在新的发行版本中会调整"最佳"指令集的定义.
目前,它等价于-xarch=v7.
generic64在多数64位平台架构上生成高性能的64位对象二进制文件.
该选项在具有64位内核的Solaris操作环境中使用高性能的最佳指令集,同时不降低操作环境的性能.
如果需要,在新的发行版本中会调整"最佳"指令集的定义.
目前,它等价于-xarch=v9.
native在本系统上生成高性能的32位对象二进制文件.
这是-fast选项的缺省值.
编译器在处理器运行的系统上选择适当的设置.
native64在本系统上生成高性能的64位对象二进制文件.
编译器在处理器运行的系统上为生成系统的64位二进制选择适当的设置.
v7编译用于SPARC-V7ISA.
在V7ISA上使编译器生成高性能代码.
这等价于在V8ISA上使用高性能的最佳指令,但不包括整数mul和div指令和fsmuld指令.
示例:SPARCstation1,SPARCstation2v8a编译用于SPARC-V8ISAV8a版本.
根据定义,V8a意味着V8ISA,但不包括fsmuld指令.
该选项在V8aISA上使编译器生成高性能代码.
示例:任何基于microSPARCI芯片架构的系统v8编译用于SPARC-V8ISA.
在V8架构上使编译器生成高性能代码.
示例:SPARCstation10附录17C++编译器选项17-69v8plus编译用于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架构上使用高性能的最佳指令集.
表Q-24SPARC平台的-xarch值(续下)isa的值含义17-70C++用户指南2004年4月另请注意:ISPARC指令集架构V7、V8和V8a全部是二进制兼容的.
I由v8plus和v8plusa编译的对象二进制文件(.
o)可以同时链接和执行,但必须在与SPARCV8plusa兼容的平台上运行.
I由v8plus、v8plusa和v8plusb编译的对象二进制文件(.
o)可以同时链接和执行,但必须在与SPARCV8plusb兼容的平台上运行.
Ixarch的值generic64、native64、v9、v9a和v9b只适用于UltraSPARC64位Solaris操作环境.
I由generic64、native64、v9和v9a编译的对象二进制文件(.
o)可以同时链接和执行,但必须在与SPARCV9a兼容的平台上运行.
I由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=v9b可用.
表Q-24SPARC平台的-xarch值(续下)isa的值含义附录17C++编译器选项17-71对于IA平台:表Q-25给出了IA平台上每个-xarch关键字的详细信息.
缺省如果未指定-xarch=isa,则假定为-xarch=generic.
交互尽管该选项可单独使用,但它是-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指定了相同的值.
表Q-25IA平台的-xarch值isa的值含义generic编译以便在多数系统上达到较高的性能.
这是缺省设置.
该选项在多数处理器上使用高性能的最佳指令集,同时不降低处理器的主要性能.
如果需要,在新的发行版本中会调整"最佳"指令集的定义.
386在该发行版本中generic和386是等价的.
pentium_pro将指令集限制到pentium_pro架构.
example%CC-xtarget=ultra2-xarch=v8plusbfoo.
cc17-72C++用户指南2004年4月Q.
2.
105-xbuiltin[={%all|%none}]启用或禁用标准库调用的最佳优化.
缺省情况下,编译器会将标准库头文件中声明的函数视为普通函数.
不过,编译器会将某些函数识别为"内部"或"内建".
视为内建函数时,编译器可以生成更有效的代码.
例如,编译器可以识别无副作用的函数,且通常为给定的相同输入返回相同的输出.
编译器可将部分函数直接生成为内联函数.
-xbuiltin=%all选项会请求编译器识别尽可能多的内建标准函数.
所识别函数的确切列表在不同的编译器代码生成器版本中各不相同.
-xbuiltin=%none选项会生成缺省编译器行为,编译器对内建函数不执行任何优化.
缺省如果未指定-xbuiltin选项,则编译器假定-xbuiltin=%none.
如果仅指定了-xbuiltin,则编译器假定-xbuiltin=%all.
交互宏-fast的扩展包括了-xbuiltin=%all.
示例下面的编译器命令请求标准库调用的特殊处理.
下面的编译器命令请求不对标准库调用进行特别处理.
注意,宏-fast的扩展包括了-xbuiltin=%all.
example%CC-xbuiltin-cfoo.
ccexample%CC-fast-xbuiltin=%none-cfoo.
cc附录17C++编译器选项17-73Q.
2.
106-xcache=cSPARC:定义优化器使用的缓存属性.
该选项指定了优化器可以使用的缓存属性,不保证使用每个特定的缓存属性.

注–该选项可单独使用,但它是-xtarget选项的部分扩展,主要用途是覆盖-xtarget选项提供的值.
值c必须是下列值之一:缓存属性的定义si/li/ai如下:例如,i=1指定了级别1缓存属性s1/l1/a1.
缺省如果未指定-xcache,则缺省假定为-xcache=generic.
该值指示了编译器在多数SPARC处理器上使用缓存属性来获得高性能,而不降低任何处理器的性能.
表Q-26-xcache的值c的值含义generic该缺省值指示了编译器在多数x86和SPARC处理器上使用缓存属性来获得高性能,而不会降低任何处理器的性能.
如果需要,在新的发行版本中会调整最佳定时属性.
native设置在主机环境中最佳性能的参数.
s1/l1/a1定义级别1缓存属性s1/l1/a1:s2/l2/a2定义级别1和2缓存属性s1/l1/a1:s2/l2/a2:s3/l3/a3定义级别1、2和3缓存属性属性定义sii级别的数据缓存大小以千字节为单位lii级别的数据缓存行大小以字节为单位aii级别的数据缓存关联17-74C++用户指南2004年4月示例-xcache=16/32/4:1024/32/1指定了:另见-xtarget=tQ.
2.
107-xcg89与-xtarget=ss2相同.
警告如果在不同的步骤中编译和链接且使用-xcg89编译,就要确保使用同一选项进行链接,否则会产生无法预料的结果.
Q.
2.
108-xcg92与-xtarget=ss1000相同.
警告如果在不同的步骤中编译和链接且使用-xcg92编译,就要确保使用同一选项进行链接,否则会产生无法预料的结果.
Q.
2.
109-xchar[=o]有些系统将字符定义成无符号类型,选项使得迁移这些系统上的代码变得容易.
如果不是从这样的系统中迁移,最好不要使用该选项.
只有那些依赖字符类型符号的程序才需要重写,它们要改写成显式指定有符号或者无符号.
级别1缓存具有级别2缓存具有16千字节1024千字节32字节行大小32字节行大小4方向关联指示映射关联附录17C++编译器选项17-75值您可以用下列值之一来替换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的符号因不同的编译器和操作系统而不同.
表Q-27-xchar值值含义signed将声明为字符的字符常量和变量视为带符号的.
这会影响编译的代码的行为,而不影响库例程的行为.
s等价于signedunsigned将声明为字符的字符常量和变量视为无符号的.
这会影响编译的代码的行为,而不影响库例程的行为.
u等价于unsigned17-76C++用户指南2004年4月Q.
2.
110-xcheck[=i]SPARC:使用-xcheck=stkovf进行编译可以在单线程程序中增加主线程的运行时检查堆栈溢出,还可以在多线程程序中增加从属线程堆栈.
如果检测到堆栈溢出,则生成SIGSEGV.
如果应用程序需要以与处理其它地址空间违例不同的方法,来处理堆栈溢出引起的SIGSEGV,那么请参阅sigaltstack(2).
值i必须是下列值之一:缺省如果未指定-xcheck,则编译器缺省为-xcheck=%none.
如果指定没有任何参数的-xcheck,编译器缺省为-xcheck=%none.
在命令行上-xcheck选项不进行累积.
编译器按照上次出现的命令设置标志.
Q.
2.
111-xchip=c指定供优化器使用的目标处理器.
-xchip选项通过指定目标处理器来指定定时属性.
该选项会影响:I指令的顺序(即调度)I编译器使用分支的方法I语义上等价于其它指令时使用的指令注–该选项可单独使用,但它是-xtarget选项的部分扩展,主要用途是覆盖-xtarget选项提供的值.
表Q-28-xcheck值值含义%all执行全部检查.
%none不执行检查.
stkovf打开堆栈溢出检查.
no%stkovf关闭堆栈溢出检查.
附录17C++编译器选项17-77值c必须是下列值之一:缺省在多数SPARC处理器中generic为缺省值,指示编译器使用最佳定时属性以获得高性能,而不降低任何处理器的性能.
表Q-29-xchip值平台c的值使用定时属性优化SPARCgeneric可以在多数SPARC处理器上获得高性能native可以在运行编译器的系统上获得高性能old早于SuperSPARC处理器的处理器superSuperSPARC处理器super2SuperSPARCII处理器micromicroSPARC处理器micro2microSPARCII处理器hyperhyperSPARC处理器hyper2hyperSPARCII处理器powerupWeitekPowerUp处理器ultraUltraSPARC处理器ultra2UltraSPARCII处理器ultra2eUltraSPARCIIe处理器ultra2iUltraSPARCIIi处理器ultra3UltraSPARCIII处理器ultra3cuUltraSPARCIIICu处理器IAgeneric多数IA处理器386Intel386处理器486Intel486处理器pentiumIntelPentium处理器pentium_proIntelPentiumPro处理器17-78C++用户指南2004年4月Q.
2.
112-xcode=aSPARC:指定代码地址空间.
注–强烈建议通过指定-xcode=pic13或-xcode=pic32来生成共享对象.
也可以使用-xarch=v9-xcode=abs64和-xarch=v8-xcode=abs32生成可用共享对象,但它们效率很低.
用-xarch=v9-xcode=abs32或-xarch=v9-xcode=abs44生成的共享对象无法工作.
值a必须是下列值之一:缺省对于SPARCV8和V7处理器,缺省为-xcode=abs32.
而对于SPARC和UltraSPARC处理器,当您使用-xarch={v9|v9a|v9b|generic64|native64}时,缺省为-xcode=abs64.
在SPARC上存在两个具有-xcode=pic13和-xcode=pic32的名义性能成本:I取决于设置为指向表(_GLOBAL_OFFSET_TABLE_)的寄存器的入口(该表用于访问共享库全局或静态变量的表),用-xcode=pic13或-xcode=pic32编译的例程会执行一些附加指令.
表Q-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个.
附录17C++编译器选项17-79I对全局或静态变量的每次访问都会通过_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选项.
Q.
2.
113-xcrossfile[=n]SPARC:启用多个源文件之间的优化和内联处理.
-xcrossfile在编译期间工作并且仅涉及出现在编译命令中的文件.
请参考下列命令行示例:跨模块优化发生在文件f1.
cc和f2.
cc之间,以及f3.
cc和f4.
cc之间.
在f1.
cc和f3.
cc或f4.
cc之间不发生优化.
%nmfile.
o|grep_GLOBAL_OFFSET_TABLE_U_GLOBAL_OFFSET_TABLE_example%CC-xcrossfile-xO4-cf1.
ccf2.
ccexample%CC-xcrossfile-xO4-cf3.
ccf4.
cc17-80C++用户指南2004年4月值n必须是下列值之一:通常,在命令行上编译器的分析范围限制到每个独立的文件.
例如,传递-xO4选项时,自动内联被限制到同一源文件中定义和引用的子程序.
编译器使用-xcrossfile或-xcrossfile=1可以分析在命令行上命名的所有文件,结果就好像这些文件被连接到单一的源文件中.
缺省如果未指定-xcrossfile,则假定-xcrossfile=0且不执行任何跨文件优化或内联.
-xcrossfile与-xcrossfile=1相同.
交互-xcrossfile选项只有与-xO4或-xO5一起使用时才有效.
警告这种编译所产生的文件由于可能的内联所以是相互依赖的,而且在将这些文件链接到程序时必须作为一个单元使用.
如果更改了任何一个例程并重新编译了文件,则必须重新编译所有的文件.
因此,使用该选项会影响makefile的结构.
另见-xldscope表Q-31-xcrossfile值n的值含义0不执行跨文件优化或跨文件内联.
1执行多个源文件之间的优化和内联处理.
附录17C++编译器选项17-81Q.
2.
114-xdumpmacros[=value[,value.
.
.
]]要查看宏在程序中如何工作时,请使用这个选项.
该选项提供了诸如宏定义、取消定义的宏和宏用法实例的信息,并按宏的处理顺序将输出打印到标准错误(stderr).
-xdumpmacros选项在整个文件中或在dumpmacros或end_dumpmacrospragma覆盖该选项之前都是有效的.
请参阅第18-5页的"#pragmadumpmacros".
值您可以用以下参数代替value:这些选项值会累积,因此指定-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.
表Q-32-xdumpmacros值值含义[no%]defs[不]打印所有宏定义[no%]undefs[不]打印所有宏取消定义[no%]use[不]打印关于所用宏的信息[no%]loc[不]打印defs、undefs和use的位置(路径名称和行号)[no%]conds[不]打印在条件指令中宏的使用信息[no%]sys[不]打印系统头文件中所有宏的定义、取消定义的宏和宏的使用信息%all将选项设置为-xdumpmacros=defs,undefs,use,loc,conds,sys.
该参数最好与其它参数的[no%]形式配合使用.
例如,-xdumpmacros=%all,no%sys将从输出排除系统头文件宏,但仍然提供所有其它宏的信息.
%none不打印任何宏信息17-82C++用户指南2004年4月示例如果使用选项-xdumpmacros=use,no%loc,则使用的每个宏名称只打印一次.
不过,要了解更多详细信息,请使用选项-xdumpmacros=use,loc,这样每次使用宏时都可以打印位置和宏的名称.
请参考以下文件t.
c:example%catt.
c#ifdefFOO#undefFOO#defineCOMPUTE(a,b)a+b#else#defineCOMPUTE(a,b)a-b#endifintn=COMPUTE(5,2);intj=COMPUTE(7,1);#ifCOMPUTE(8,3)+NN+MMintk=0;#endif附录17C++编译器选项17-83以下示例显示了基于defs、undefs、sys和loc参数的文件t.
c的输出.
example%CC-c-xdumpmacros-DFOOt.
c#define__SunOS_5_71#define__SUNPRO_CC0x550#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.
ccommandline:#define__SunOS_5_71commandline:#define__SUNPRO_CC0x550commandline:#defineunix1commandline:#definesun1commandline:#definesparc1commandline:#define__sparc1commandline:#define__unix1commandline:#define__sun1commandline:#define__BUILTIN_VA_ARG_INCR1commandline:#define__SVR41commandline:#define__SUNPRO_CC_COMPAT5commandline:#define__SUN_PREFETCH1commandline:#defineFOO1commandline:#undefBARt.
c,line2:#undefFOOt.
c,line3:#defineCOMPUTE(a,b)a+b17-84C++用户指南2004年4月以下示例说明了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:usedmacroX附录17C++编译器选项17-85Q.
2.
115-xe仅检查语法和语义错误.
指定-xe时,编译器不生成任何目标代码.
-xe的输出被指向stderr.
如果不需要编译器生成目标文件,就可以使用-xe选项.
例如,如果要使用删除代码的方法来确定导致错误消息的原因,使用-xe可以加速编辑、编译周期.
另见-cQ.
2.
116-xF[=v[,v.
.
.
]]使链接程序能对函数和变量重组以达到最优.
该选项指示编译器将函数和(或)数据变量放置到单独的分段中,这使链接程序(使用链接程序的-M选项指定的mapfile中的方向)能将这些段重组以优化程序性能.
通常,该优化仅在缺页时间构成程序运行时间的一大部分时才有效.
重组变量有助于解决对运行时性能产生负面影响的以下问题:I在内存中存放位置很近的无关变量会造成缓存和页的竞争.
I在内存中存放位置很远的相关变量会造成过大的工作集.
I未用到的弱变量副本会造成过大的工作集,从而降低有效数据密度.
重组变量和函数以优化性能,需要执行以下操作:1.
使用-xF进行编译和链接.
2.
关于如何生成函数的mapfile请遵循《程序性能分析工具》手册的说明,而关于如何生成数据的mapfile请遵循"LinkerandLibrariesGuide"中的说明.
3.
通过使用链接程序的-M选项与新的mapfile重新链接.
4.
在分析器下重新执行以验证是否改进.
17-86C++用户指南2004年4月值v可以是下列值中的一个或多个:缺省如果未指定-xF,则缺省为-xF=%none.
如果指定了没有参数的-xF,则缺省为-xF=%none,func.
交互使用-xF=lcldata可以禁止某些地址计算优化,因此如果实验证明它是有效的,则只能使用该标志.
另见analyzer(1)、debugger(1)、ld(1)手册页Q.
2.
117-xhelp=flags显示了对每个编译器选项的简要描述.
Q.
2.
118-xhelp=readme显示了联机readme文件的目录.
在环境变量PAGER中指定的命令标明了readme文件的页数.
如果未设置PAGER,则缺省的分页命令为more.
表Q-33-xF值值含义[no%]func[不]将函数分段到单独的段中.
[no%]gbldata[不]将全局数据(具有外部链接的变量)分段到单独的段中.
[no%]lcldata[不]将局部数据(具有内部链接的变量)分段到单独的段中.
%all分段函数、全局数据和局部数据.
%none不分段.
附录17C++编译器选项17-87Q.
2.
119-xiaSPARC:链接合适的区间运算库并设置适当的浮点环境.
注–C++区间运算库与Fortran编译器中实现的区间运算相兼容.
扩展-xia选项是扩展到-fsimple=0-ftrap=%none-fns=no-library=interval的宏.
交互要使用区间运算库,请包括.
使用区间运算库时,必须包括下列库之一:libC、Cstd或iostreams.
关于包括这些库的详细信息请参阅-library.
警告如果使用了区间并为-fsimple、-ftrap或-fns指定了不同的值,那么您的程序可能会产生错误行为.
C++区间运算处于实验阶段且正在改进.
不同的发行版本具有不同的功能.
另见C++IntervalArithmeticProgrammingReference,IntervalArithmeticSolvesNonlinearProblemsWhileProvidingGuaranteedResults(http://www.
sun.
com/forte/info/features/intervals.
html),-library17-88C++用户指南2004年4月Q.
2.
120-xildoff关闭增量式链接程序.
缺省如果不使用-g选项,则假定为该选项.
使用-G选项或在命令行上命名任意源文件时,也假定为该选项.
使用-xildon选项覆盖该缺省值.
另见-xildon、ild(1)手册页、ld(1)手册页和《C用户指南》中的"增量式链接编辑器"Q.
2.
121-xildon打开增量式链接程序.
如果您使用的是-g而不是-G并且未在命令行上命名任何源文件,则假定为该选项.
使用-xildoff选项覆盖该缺省.
另见-xildoff、ild(1)手册页、ld(1)手册页和《C用户指南》中的"增量式链接编辑器"Q.
2.
122-xinline[=func_spec[,func_spec.
.
.
]]指定了在-xO3或更高级别上优化器可以内联哪些用户编写的例程.
附录17C++编译器选项17-89值func_spec必须是下列值之一.
只有使用-xcrossfile[=1],正在编译文件中的例程才会考虑链接.
优化器决定适合内联的例程.
缺省如果未指定-xinline选项,则编译器假设-xinline=%auto.
如果指定了没有参数的-xinline=,则不内联任何函数,这与优化的级别无关.
示例要在禁用函数(该函数声明了intfoo())的内联时启用自动内联,请使用要强烈请求声明为intfoo()的函数的内联,并将所有其它函数作为内联的候选,请使用要强烈请求声明为intfoo()的函数的内联,且不允许任何其它函数的内联,请使用表Q-34-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.
cc17-90C++用户指南2004年4月交互-xinline选项对低于-xO3优化级别的函数无效.
若在-xO4或更高级别上,则优化器决定哪些函数应该内联,而无需指定-xinline选项.
若在-xO4或更高级别上,编译器也尝试决定哪些函数内联后可以提高性能.
如果出现以下任一情况,则不内联例程.
不会省略任何警告.
I优化级别低于-xO3I无法找到例程I内联无益或不安全I源码不在正被编译的文件中,或者如果使用-xcrossfile[=1],则源码不在命令行上所命名的文件中警告如果使用-xinline强制内联一个函数,实际上就会降低性能.
另见-xldscopeQ.
2.
123-xipo[={0|1|2}]执行过程间的优化.
-xipo选项通过调用过程间分析传递,来执行整个程序的优化.
与-xcrossfile不同的是-xipo按链接步骤对所有目标文件执行优化,而且优化不只限于编译命令上的源文件.
-xipo选项特别适用于编译和链接较大的多文件应用程序.
用该标志编译的目标文件具有在这些文件内编译的分析信息,这些信息实现了在源码和预编译的程序文件中的过程间分析.
不过,分析和优化只限于用-xipo编译的目标文件,而不扩展到库的目标文件.
附录17C++编译器选项17-91值-xipo选项可以具有以下值.
缺省如果未指定-xipo,则假定为-xipo=0.
如果仅指定了-xipo,则假定为-xipo=1.
示例以下示例在相同的步骤中编译和链接.
优化器在三个源文件之间执行crossfile内联.
该操作在链接的最后一步完成,因此源文件的所有编译不必全在单一的编译中完成,而且这些源文件的编译会覆盖许多独立的编译,其中每个编译都会指定-xipo选项.
以下示例在不同的步骤中编译和链接.
在编译步骤中创建的目标文件具有在这些文件内编译的附加分析信息,这样就可以在链接步骤中执行crossfile优化.
交互-xipo选项要求的最低优化级别为-xO4.
在同一编译器命令行上不能同时使用-xipo选项和-xcrossfile选项.
表Q-35-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.
o17-92C++用户指南2004年4月警告在不同的步骤中编译和链接时,必须在两个步骤中都指定-xipo才是有效的.
未使用-xipo编译的对象可以与使用-xipo编译的对象自由链接.
即使使用-xipo进行编译时,库也不参与crossfile的过程间分析,如以下示例所示.
在该示例中,在one.
cc、two.
cc和three.
cc之间,main.
cc和four.
cc之间执行过程间的优化,而不在main.
cc或four.
cc和mylib.
a中的例程之间执行过程间优化.
(第一个编译可能生成有关未定义符号的警告,但仍可执行过程间优化,因为过程间优化是编译和链接的一个步骤.
)由于在多个文件之间执行优化所需的附加信息,-xipo选项生成了更大的目标文件.
不过,该附加信息不会成为最后可执行的二进制文件的一部分.
可执行程序大小的增加都是由于执行的附加优化导致的.
另见-xjobsQ.
2.
124-xjobs=n指定-xjobs选项用来设定编译器创建多少个进程来完成它的任务.
在多cpu机器上,该选项可以减少生成时间.
目前,-xjobs只在与-xipo一起使用时才有效.
如果指定-xjobs=n,过程间调用优化器在编译不同的文件时会用n作为它能启动的代码生成器实例的最大数.
值必须带值来指定-xjobs.
否则会发出错误诊断并使编译终止.
通常,n的安全值等于1.
5乘以可用处理器的数量.
由于在产生的作业间切换的相关重载,使用等于可用处理器数量整数倍的值会降低性能.
此外,如果使用很大的数值会耗尽系统资源(如交换空间).
example%CC-xipo-xO4one.
cctwo.
ccthree.
ccexample%CC-xar-omylib.
aone.
otwo.
othree.
o.
.
.
example%CC-xipo-xO4-omyprogmain.
ccfour.
ccmylib.
a附录17C++编译器选项17-93缺省出现最合适的实例之前,-xjobs的多重实例在命令行上会互相覆盖.
示例以下示例在有两个处理器的系统上进行编译时比不使用-xjobs选项而使用相同命令进行编译时更为快速.
Q.
2.
125-xlang=language[,language]包含适当的运行库,并确保指定语言的正确运行时环境.
值language必须是f77、f90或f95.
f90与f95参数是等价的.
交互-xlang=f90和-xlang=f95选项表明了-library=f90,而-xlang=f77选项表明了-library=f77.
不过,要进行混合语言链接只有-library=f77和-library=f90选项是不够的,因为只有-xlang选项才能确保正确的运行时环境.
要决定在混合语言链接中使用的驱动程序,请使用下列语言分层结构:1.
C++2.
Fortran95(或Fortran90)3.
Fortran774.
C或C99将Fortran95、Fortran77和C++目标文件链接在一起时,请使用最高级语言的驱动程序.
例如,使用下列C++编译器命令来链接C++和Fortran95的目标文件.
example%CC-xipo-xO4-xjobs=3t1.
cct2.
cct3.
ccexample%CC-xlang=f95.
.
.
17-94C++用户指南2004年4月要链接Fortran95和Fortran77的目标文件,请使用如下所示的Fortran95驱动程序.
在相同的编译器命令中不能同时使用-xlang选项和-xlic_lib选项.
如果正使用-xlang并且要在SunPerformanceLibraries中进行链接,那么请使用-library=sunperf.
警告不要同时使用-xnolib和-xlang.
如果使用C++对象来混合并行的Fortran对象,链接行就必须指定-mt标志.
另见-library,-staticlibQ.
2.
126-xldscope={v}指定-xldscope选项更改用于定义外部符号的缺省链接程序作用域.
由于更好的隐藏了实现,所以对缺省的更改会产生更快速更安全的共享库和可执行文件.

example%f95-xlang=f77.
.
.
附录17C++编译器选项17-95值v必须是下列值之一:缺省如果未指定-xldscope,则编译器假定-xldscope=global.
如果指定了没有任何值的-xldscope,编译器就会产生错误.
出现最合适的实例之前,该选项的多重实例在命令行上会互相覆盖.
警告如果要使客户端覆盖库中的函数,就必须确保该库生成期间函数不生成内联.
如果使用-xinline指定函数名称,如果在可以自动内联的-xO4或更高级别进行编译,如果使用内联说明符,或如果正使用跨文件的优化,那么编译器内联函数.
例如,假定库ABC具有缺省的分配器函数,该函数可用于库的客户端,也可在库的内部使用:void*ABC_allocator(size_tsize){returnmalloc(size);}如果在-xO4或更高级别生成库,则编译器内联库组件中出现的对ABC_allocator的调用.
如果库的客户端要用定制的版本替换ABC_allocator,则在调用ABC_allocator的库组件中不能进行该替换.
最终程序将包括函数的不同版本.
生成库时,用__hidden或__symbolic说明符声明的库函数可以内联生成.
假定这些库函数不被客户端覆盖.
请参阅第4-3页的"线程局部存储".
用__global说明符声明的库函数不应内联声明,并且应该使用-xinline编译器选项来防止内联.
表Q-36-xldscope值值含义global全局链接程序作用域是限制最少的链接程序作用域.
对符号的所有引用都绑定到定义符号的第一个动态装入模块中的定义.
该链接程序作用域是外部符号的当前链接程序作用域.
symbolic符号链接程序作用域比全局链接程序作用域具有更多的限制.
将对链接的动态装入模块内符号的所有引用绑定到模块内定义的符号.
在模块外部,符号也则被视为全局符号.
该链接程序作用域对应于链接程序选项-Bsymbolic.
尽管不能与C++库一起使用-Bsymbolic,但是可以使用不会引起问题的-xldscope=symbolic.
关于链接程序的更多信息,请参阅ld(1).
hidden隐藏链接程序作用域具有比符号和全局链接程序作用域更高的限制.
将动态装入模块内的所有引用绑定到该模块内的定义.
符号在模块外部是不可视的.
17-96C++用户指南2004年4月另见-xinline、-xO、-xcrossfileQ.
2.
127-xlibmieee在异常情况下,使libm返回数学例程的IEEE754值.
libm的缺省行为是兼容XPG.
另见《数值计算指南》Q.
2.
128-xlibmil内联选定libm库例程用于优化.
注–该选项不影响C++内联函数.
对于部分libm库例程存在可用的内联模板.
该选项为当前使用的浮点选项和平台选择这些内联模板,生成执行速度最快的可执行文件.
交互-fast选项中隐含了这个选项.
另见-fast、《数值计算指南》附录17C++编译器选项17-97Q.
2.
129-xlibmopt使用优化数学例程的库.
该选项使用了优化性能的数学例程库,并且通常会生成运行速度更快的代码.
这样生成的代码可能与普通数学库生成的代码稍有不同,不同之处通常在最后一位上.

该库选项在命令行上的顺序并不重要.
交互-fast选项中隐含了这个选项.
另见-fast,-xnolibmoptQ.
2.
130-xlic_lib=sunperfSPARC:在SunPerformanceLibrary中链接.
该选项(如-l)应该出现在命令行的末尾,位于源文件或目标文件之后.
注–推荐使用-library=sunperf选项来链接SunPerformanceLibrary,因为该选项可以确保这些库按照正确的顺序链接.
此外,-library=sunperf选项与位置无关(它可以出现在命令行的任何位置),并且可以使用-staticlib静态链接SunPerformanceLibrary.
-staticlib选项比-Bstatic-xlic_lib=sunperf-Bdynamic组合更方便使用.
交互在相同的编译器命令中不能同时使用-xlang选项和-xlic_lib选项.
如果正使用-xlang并且要在SunPerformanceLibraries中进行链接,那么请使用-library=sunperf.
不能在相同的编译器命令中同时使用-library=sunperf和-xlic_lib=sunperf.
17-98C++用户指南2004年4月静态链接SunPerformanceLibrary时推荐使用-library=sunperf和-staticlib=sunperf选项,如下例所示.
如果您选择使用-xlic_lib=sunperf选项而不是-library=sunperf,那么请使用-Bstatic选项,如下例所示.
另见-library和performance_library自述文件Q.
2.
131-xlicinfo显示许可证服务器信息.
该选项为检验了许可证的每个用户返回许可证服务器的名称和用户ID.
Q.
2.
132-xlinkopt[=level]指示编译器在目标文件中的任何优化上生成的可执行文件或动态库上,执行链接时优化.

这些优化在链接时通过分析对象二进制代码执行.
虽然未重写目标文件,但产生的可执行代码可能与初始对象的代码不同.
必须至少在部分编译命令中使用-xlinkopt,才能使-xlinkopt在链接时有效.
优化器仍可以在未使用-xlinkopt进行编译的对象二进制文件上执行部分受限的优化.
-xlinkopt优化出现在编译命令行上的静态库代码,但会跳过出现在命令行上的共享(动态)库代码而不对其进行优化.
当生成共享库时(使用-G编译),也可以使用-xlinkopt.
example%CC-library=sunperf-staticlib=sunperf.
.
.
(推荐使用)%CC.
.
.
-Bstatic-xlic_lib=sunperf-Bdynamic.
.
.
附录17C++编译器选项17-99值级别必须将执行的优化级别设置为0、1或2.
各优化级别如下所示:如果在不同的步骤中编译,则-xlinkopt必须同时出现在编译和链接步骤中:example%cc-c-xlinkopta.
cb.
cexample%cc-omyprog-xlinkopt=2a.
o注意,仅当链接编译器时才使用级别参数.
在以上示例中,即使编译对象二进制文件时使用的是隐含的级别1,链接优化器的级别仍然是2.
缺省不用级别参数来指定的-xlinkopt隐含了-xlinkopt=1.
交互当编译整个程序并且使用配置文件反馈时,该选项才最有效.
配置会显示代码中最常用和最少用的部分并相应地指导优化器集中其努力方向.
这对大型应用非常重要,因为链接时执行代码地优化放置可以减少指令的高速缓存缺失.
一般来说,编译如下所示:关于使用配置文件反馈的详细信息,请参阅第17-123页的"-xprofile=p".
警告您不能同时使用链接时链接优化器和增量式链接程序ild.
-xlinkopt将缺省链接程序设置为ld.
如果使用-xildon显式启用增量式链接程序并指定-xlinkopt,那么-xlinkopt被禁用.
表Q-37-xlinkopt值链接优化器设置行为0禁用链接优化器.
(这是缺省情况.
)1在链接时根据控制流分析执行优化,其中包括指令缓冲着色和分支优化.
2在链接时执行附加的数据流分析,其中包括终止的代码排除和地址计算简化.
example%cc-oprogt-xO5-xprofile=collect:progfile.
cexample%progtexample%cc-oprog-xO5-xprofile=use:prog-xlinkoptfile.
c17-100C++用户指南2004年4月使用-xlinkopt编译时,请不要使用-zcompreloc链接程序选项.
注意,使用该选项编译会略微延长链接的时间,也会增加目标文件的大小,但可执行文件的大小保持不变.
使用-xlinkopt和-g编译会将调试信息包括在内,从而增加了可执行文件的大小.
Q.
2.
133-xM在命名的C++程序上只运行预处理程序,同时请求该程序生成makefile依存性并将结果发送到标准输出(关于make文件和依存的详细信息,请参阅make(1)).
示例例如:生成的输出如下:另见make(1S)(关于makefile和依存性的详细信息)Q.
2.
134-xM1该选项除了不报告/usr/include头文件的依存性,也不报告编译器提供的头文件的依存性之外,与-xM相同.
#includevoidmain(void){}e.
o:e.
ce.
o:/usr/include/unistd.
he.
o:/usr/include/sys/types.
he.
o:/usr/include/sys/machtypes.
he.
o:/usr/include/sys/select.
he.
o:/usr/include/sys/time.
he.
o:/usr/include/sys/types.
he.
o:/usr/include/sys/time.
he.
o:/usr/include/sys/unistd.
h附录17C++编译器选项17-101Q.
2.
135-xMergeSPARC:将数据段和文本段合并.
除非使用ld-N进行链接,否则目标文件中的数据为只读并在进程间共享.
另见ld(1)手册页Q.
2.
136-xmemalign=ab使用-xmemalign选项用来控制编译器对数据对齐的假设.
通过控制可能会出现非对齐内存访问的代码和出现非对齐内存访问时的处理程序,可以更轻松的将程序移植到SPARC.
指定最大的假定内存对齐和未对齐的数据访问行为.
在a(对齐)和b(行为)之间必须有一个值.
a指定了最大假定内存对齐,而b指定了未对齐的内存访问行为.
对于可在编译时决定对齐的内存访问,编译器会为数据对齐生成适当的装入/存储指令序列.
对于不能在编译时决定对齐的内存访问,编译器必须假定一个对齐以生成所需的装入/存储序列.
值下表列出了-xmemalign的对齐和行为的值表Q-38-xmemalign的对齐和行为值ab1假定最多1字节对齐.
i解释访问并继续执行.
2假定最多2字节对齐.
s产生信号SIGBUS.
4假定最多4字节对齐.
f为小于或等于4的对齐产生信号SIGBUS,否则解释访问并继续执行.
8假定最多8字节对齐.
16假定最多16字节对齐17-102C++用户指南2004年4月缺省下面是-xmemalign的缺省值.
以下缺省值仅适用于-xmemalign标志不出现时:I当-xarch的值是generic、v7、v8、v8a、v8plus、v8plusa时,缺省值为-xmemalgin=4s.
I当-xarch的值是v9、v9a时,缺省值为-xmemalign=8s.
在出现-xmemalign标志但未给出任何值时,缺省值为:I所有-xarch值的-xmemalign=1i.
示例下表说明了如何使用-xmemalign来处理不同的对齐情况.
Q.
2.
137-xnativeconnect[=i]要将接口信息包括在目标文件及后续共享库内部时,请使用-xnativeconnect选项,这样共享库就可以与用Java编程语言(Java代码)编写的代码接口.
当使用-G生成共享库时,也必须包括-xnativeconnect.
当用-xnativeconnect编译时,可以提供最大的外部可视本地代码接口.
"本地连接器工具"(NativeConnectorTool,NCT)能够自动生成Java代码和Java本地接口(JNI)代码.
一起使用-xnativeconnect和NCT可以使C++共享库中的函数能从Java代码进行调用.
关于如何使用NCT的更多信息请参阅联机帮助.
表Q-39-xmemalign示例命令情况-xmemalign=1s大量未对齐访问导致了自陷处理非常缓慢.
-xmemalign=8i在发生错误的代码中存在偶然的、有目的的、未对齐的访问.
-xmemalign=8s程序中应该没有任何未对齐访问.
-xmemalin=2s要检查可能的奇数字节访问.
-xmemalign=2i要检查可能的奇数字节访问并要程序工作.
附录17C++编译器选项17-103值i必须是下列值之一:缺省I如果未指定-xnativeconnect,则编译器将选项设置为-xnativeconnect=%none.
I如果仅指定了-xnativeconnect,则编译器将选项设置为-xnativeconnect=inlines,interfaces.
I该选项不累积.
编译器使用指定的最后一个设置.
例如,如果您指定了:则编译器将选项设置为-xnativeconnect=no%inlines,interfaces.
警告如果计划使用-xnativeconnect,不要用-compat=4进行编译.
记住,如果指定没有参数的-compat,则编译器将其设置为-compat=4.
如果未指定-compat,编译器将其设置为-compat=5.
您还可以通过-compat=5将其显式设置为兼容模式.
Q.
2.
138-xnolib禁止链接缺省系统库.
通常(不含该选项)情况下,C++编译器会链接多个系统库以支持C++程序.
-llib选项使用这个选项来链接没有传递给ld的缺省系统库.
通常情况下,编译器按照以下顺序链接系统支持库:表Q-40-xnativeconnect值值含义%all生成-xnativeconnet各选项所描述的全部不同数据.
%none不生成-xnativeconnet各选项所描述的任何不同数据.
[no%]inlines强制生成已引用内联函数的行外实例.
它提供具有外部可视方法的本机连接器来调用内联函数.
调用点中的函数普通内联不受其影响.
[no%]interfaces强制生成"二进制接口描述符"(BinaryInterfaceDescriptors,BIDS)CC-xnativeconnect=inlinesfirst.
o-xnativeconnect=interfacessecond.
o-O-G-olibrary.
so17-104C++用户指南2004年4月I在标准模式(缺省模式)下:I在兼容模式(-compat)下:-l选项的顺序非常重要.
-lm、-lw和-lcx选项必须在-lc之前出现.
注–如果指定了-mt编译器选项,编译器通常就在链接-lm之前对-lthread进行链接.
要决定在缺省情况下链接的系统支持库,请使用-dryrun选项进行编译.
例如,以下命令的输出:在输出中包括了以下内容:注意,当指定-xarch=v9时,不链接-lcx.
示例对于符合C应用程序二进制接口的基本编译(即只支持C所需的C++程序),请使用:要将libm静态链接到具有通用架构指令集合的单线程应用程序,请使用:I标准模式下:-lCstd-lCrun-lm-lw-lcx-lc-lC-lm-lw-lcx-lcexample%CCfoo.
cc-xarch=v9-dryrun-lCstd-lCrun-lm-lw-lcexample%CC-xnolibtest.
cc-lcexample%CC-xnolibtest.
cc-lCstd-lCrun-Bstatic-lm\-Bdynamic-lw-lcx-lc附录17C++编译器选项17-105I兼容模式下:交互使用-xarch=v9,-xarch=v9a或-xarch=v9b链接时,某些诸如libm.
a和libc.
a的静态系统库不可用.
如果指定了-xnolib,就必须按给定的顺序手动链接所有需要的系统支持库.
必须最后链接系统支持库.
如果指定了-xnolib,则忽略-library.
警告许多C++语言特性需要使用libC(兼容模式下)或libCrun(标准模式下).
系统支持库的集合不稳定,会因不同的发行版本而更改.
在64位编译模式下,不出现-lcx.
另见-library,-staticlib,-lQ.
2.
139-xnolibmil在命令行上取消-xlibmil.
将该选项与-fast一起使用以覆盖对优化数学库的链接.
Q.
2.
140-xnolibmopt不使用数学例程库.
example%CC-compat-xnolibtest.
cc-lC-Bstatic-lm\-Bdynamic-lw-lcx-lc17-106C++用户指南2004年4月示例在命令行上在-fast选项之后使用该选项,如下例所示:Q.
2.
141-xOlevel指定优化级别,注意大写字母O要后跟数字1、2、3、4或5.
通常,程序执行速度取决于优化的级别.
优化级别越高,运行时性能越好.
不过,较高的优化级别会延长编译时间并生成较大的可执行文件.
某些情况下,-xO2的执行可能比其它优化级别好,而-xO3也可能胜过-xO4.
尝试用每个级别编译以查看您是否会遇到这种少见的情况.
如果优化器运行时内存不足,则会尝试在较低的优化等级上重试当前过程来恢复.
优化器在-xOlevel选项中指定的初始级别中恢复随后的过程.
有五个级别可以与-xO一起使用.
以下几节描述了在SPARC平台和x86平台上如何操作这些级别.
值在SPARC平台上:I-xO1只执行最小量的优化(peephole),也称为postpass,即汇编级优化.
如果使用-xO2或-xO3导致了过多的编译时间,或者您所使用的交换空间不足,那么可以使用-xO1.
I-xO2执行基本的局部和全局优化,其中包括:I感应变量消除I局部和全局的通用子表达式消除I代数运算简化I复制传播I常量传播I非循环变体优化I寄存器分配I基本块合并I尾部递归消除I终止代码消除I尾部调用消除I复杂表达式扩展该级别不优化外部变量或间接变量的引用或定义.
-O选项与-xO2选项等价.
example%CC-fast-xnolibmopt附录17C++编译器选项17-107I-xO3除了在-xO2级别执行的优化以外,还优化外部变量的引用和定义.
该级别不跟踪指针赋值的结果.
编译volatile没有正确保护的设备驱动程序或编译修改信号处理程序内外部变量的程序时,请使用-xO2.
通常,如果不将该级别与-xspace选项组合,就会增加代码的大小.
I-xO4除执行-xO3的优化之外,还自动内联包含在同一文件中的函数.
自动内联通常会提高执行速度,但有时却会使速度变得更慢.
通常,如果不将该级别与-xspace选项组合,就会增加代码的大小.
I-xO5生成最高级别的优化.
它只适用于占用大量计算机时间的小部分程序.
该级别采用了占用更多编译时间或无法在某种程度上减少执行时间的优化算法.
如果使用配置文件反馈执行该级别上的优化,则更容易提高性能.
请参阅第17-123页的第Q.
2.
152节"-xprofile=p".
在x84平台上:I-xO1执行基本优化.
其中包括代数运算简化、寄存器分配、基本块合并、终止代码和存储消除以及peephole优化.
I-xO2执行局部通用子表达式消除、局部复制传播、常量传播、尾部递归消除和级别1执行的优化.
I-xO3执行全局通用子表达式的消除、全局的复制传播和常量传播、循环长度简约、感应变量消除、循环变体优化和级别2执行的优化.
I-xO4自动内联包含在同一文件中的函数和级别3执行的优化.
这种自动内联通常会提高执行速度,但有时却会使速度变得更慢.
该级别还释放了通用的框架指针注册(ebp).
通常该级别会增加代码的大小.
I-xO5生成最高级别的优化.
该级别采用了占用更多编译时间或无法在某种程度上减少执行时间的优化算法.
交互如果您使用-g或-g0,且优化级别是-xO3或更低,那么编译器会尽力提供几乎全部优化的符号信息.
尾部调用优化和后端内联被禁用.
如果您使用-g或-g0,且优化级别是-xO4或更高,那么编译器会尽力提供全部优化的符号信息.
使用-g进行调试时不禁止-xO级别,但-xO级别会以某些方法限制-g.
例如,-xO级别的选项会降低调试的公用性,因此无法显示dbx中的变量,但仍可使用dbxwhere命令获取符号回溯.
更多信息请参阅《使用dbx调试程序》.
-xcrossfile选项只有与-xO4或-xO5一起使用时才有效.
-xinline选项对低于-xO3优化级别的函数无效.
若在-xO4级别上,则优化器决定哪些函数应该内联,而与是否指定-xinline选项无关.
在-xO4级别,编译器还尝试决定哪些函数内联后可以提高性能.
如果使用-xinline强制内联一个函数,实际上就会降低性能.
17-108C++用户指南2004年4月缺省缺省为不优化.
不过,只有不指定优化级别时才使用缺省.
如果指定了优化级别,则没有任何选项可以关闭优化.
如果尝试避免设置优化级别,那么请不要指定任何隐含优化级别的选项.
例如,-fast是设置优化级别为-xO5的宏选项.
隐含优化级别的所有其它选项给出优化已设置的警告消息.
不使用任何优化来编译的一种方法是从命令行删除所有选项或创建指定优化级别的文件.
警告如果在-xO3或-xO4级别上优化很大的过程(一个过程具有数千行代码),则编译器会需要非常多的内存.
在这些情况下,机器的性能就会降低.
为了防止性能的降低,请使用limit命令来限制单一进程可使用的虚拟内存大小(请参阅csh(1)手册页).
例如,将虚拟内存限制为16MB:如果虚拟内存达到16MB的数据空间,该命令会使优化器尝试恢复.
限制不能大于机器总的可用交换空间,而且要足够的小以允许在大型编译的过程中机器可以正常使用.
数据大小的最佳设置取决于要求的优化程度、真实内存和可用虚拟内存的大小.

要查找实际的交换空间,请输入:swap-l要查找实际的真实内存,请输入:dmesg|grepmem另见-xldscope-fast、-xcrossfile=n、-xprofile=p、csh(1)手册页example%limitdatasize16M附录17C++编译器选项17-109Q.
2.
142-xopenmp[=i]SPARC:使用-xopenmp选项启用具有OpenMP指令的显式并行.
实现包括了一组源代码指令、运行时库例程和环境变量.
值下表列出了i的值:缺省如果未指定-xopenmp,则编译器将选项设置为-xopenmp=none.
如果指定了没有参数的-xopenmp,则编译器将选项设置为-xopenmp=parallel.
警告在将来的发行版本中,-xopenmp的缺省可能更改.
可以通过显式指定适当的优化来避免警告消息.
如果在不同的步骤中编译和链接,那么也可以在链接步骤中指定-xopenmp.
这在编译包含OpenMP指令的库时尤其重要.
另见关于生成多进程应用程序的OpenMPFortran95、C和C++应用程序编程接口(API)的完整摘要,请参阅《OpenMPAPI用户指南》.
表Q-41-xopenmp值i的值含义parallel启用OpenMPpragma的识别.
低于-xopenmp=parallel的最小优化级别是-x03.
如果需要,编译器就将较低级别的优化更改为-x03,并发出警告.
stubs禁用对OpenMPpragma的识别,链接到存根库例程且不更改优化级别.
如果应用程序对OpenMP运行时库例程执行显式调用,并且要编译该应用程序使其能串行执行,就请使用此选项.
-xopenmp=stubs命令还定义了_OPENMP预处理程序标记.
none禁用对OpenMPpragma的识别,不更改程序的优化级别且不预定义任何预处理程序标记.
17-110C++用户指南2004年4月Q.
2.
143-xpagesize=n(SPARC)设置堆栈和堆想要的页面大小.
值n值必须是下列值之一:8K、64K、512K、4M、32M、256M、2G、16G或default.
您必须在目标平台上为Solaris操作环境指定正确的页面大小,其值由getpagesize(3C)返回.
如果您不指定有效的页面大小,则运行时请求就会被忽略.
Solaris操作环境不保证支持页面大小的请求.
您可以使用pmap(1)或meminfo(2)来决定目标平台的页面大小.
注–Solaris7和Solaris8操作环境不支持该特性.
在Solaris7和Solaris8操作环境不链接使用该选项编译的程序.
缺省如果指定-xpagesize=default,则Solaris操作环境设置页面大小.
没有参数的-xpagesize等价于-xpagesize=default.
扩展该选项其实是代表-xpagesize_heap和-xpagesize_stack的宏.
这两个选项与-xpagesize接受相同的参数:8K、64K、512K、4M、32M、256M、2G、16G或default.
可以通过指定-xpagesize来使用相同的值设置这两个选项,或使用不同的值对其进行分别指定.
警告只有在编译时和链接时使用-xpagesize选项,该选项才是有效的.
另见使用该选项进行编译与使用等价的选项将LD_PRELOAD环境变量设置为mpss.
so.
1或在运行程序之前使用等价的选项运行Solaris9命令ppgsz(1)具有相同的效果.
详细信息请参阅Solaris9手册页.
附录17C++编译器选项17-111Q.
2.
144-xpagesize_heap=n(SPARC)在内存中为堆设置页面大小.
值n可以是8K、64K、512K、4M、32M、256M、2G、16G或default.
您必须在目标平台上为Solaris操作环境指定正确的页面大小,其值由getpagesize(3C)返回.
如果不指定有效的页面大小,运行时该请求就会被忽视.
您可以使用pmap(1)或meminfo(2)来决定目标平台的页面大小.
注–Solaris7和Solaris8操作环境不支持该特性.
在Solaris7和Solaris8操作环境不链接使用该选项编译的程序.
缺省如果指定-xpagesize_heap=default,则Solaris操作环境设置页面大小.
没有参数的-xpagesize_heap等价于-xpagesize_heap=default.
另见使用该选项进行编译与使用等价的选项将LD_PRELOAD环境变量设置为mpss.
so.
1或在运行程序之前使用等价的选项运行Solaris9命令ppgsz(1)具有相同的效果.
详细信息请参阅Solaris9手册页.
Q.
2.
145-xpagesize_stack=n(SPARC)在内存中为堆栈设置页面大小.
值n可以是8K、64K、512K、4M、32M、256M、2G、16G或default.
您必须在目标平台上为Solaris操作环境指定正确的页面大小,其值由getpagesize(3C)返回.
如果不指定有效的页面大小,运行时该请求就会被忽视.
您可以使用pmap(1)或meminfo(2)来决定目标平台的页面大小.
注–Solaris7和Solaris8操作环境不支持该特性.
在Solaris7和Solaris8操作环境不链接使用该选项编译的程序.
17-112C++用户指南2004年4月缺省如果指定-xpagesize_stack=default,则Solaris操作环境设置页面大小.
没有参数的-xpagesize_stack等价于-xpagesize_stack=default.
另见使用该选项进行编译与使用等价的选项将LD_PRELOAD环境变量设置为mpss.
so.
1或在运行程序之前使用等价的选项运行Solaris9命令ppgsz(1)具有相同的效果.
详细信息请参阅Solaris9手册页.
Q.
2.
146-xpch=v该编译器选项激活了预编译头文件特性.
预编译头文件的作用是减少源代码共享同一组包含文件的应用程序的编译时间,而且这些包含文件往往有大量的源代码.
编译器首先从一个源文件收集一组头文件信息,然后在重新编译该源文件或者其它有同样头文件的源文件时就可以使用这些收集到的信息.
编译器收集的信息存储在预编译头文件中.
要使用这个特性,需要指定-xpch和-xpchstop选项,并同时使用#pragmahdrstop指令.
另见:I第17-115页的"-xpchstop=file"I"hdrstop"onpage2-13创建预编译头文件在指定-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指定了两个源文件,所以它是无效的.
附录17C++编译器选项17-113使用预编译头文件指定-xpch=use:pch_filename使用预编译头文件.
您可以将包括文件同一序列中任意数量的源文件指定为用于创建预编译头文件的源文件.
例如,use模式下的命令可显示为:CC-xpch=use:foo.
Cpchfoo.
cbar.
ccfoobar.
cc.
如果下列情况为真,就只应使用现有的预编译头文件.
如果以下任意情况都为假,就应该重新创建预编译头文件:I用于访问预编译头文件的编译器与创建预编译头文件的编译器相同.
编译器的一个版本创建的预编译头文件可能无法用于另一版本(包括安装的修补程序产生的不同之处).
I除-xpch选项之外,用-xpch=use指定的编译器选项必须与创建预编译头文件时指定的选项相匹配.
I用-xpch=use指定的包括头文件的集合与创建预编译头文件时指定的头文件集合是相同的.
I用-xpch=use指定的包括头文件的内容与创建预编译头文件时指定的包括头文件的内容是相同的.
I当前目录(即发生编译并尝试使用给定预编译头文件的目录)与创建预编译头文件所在的目录相同.
I在用-xpch=collect指定的文件中预处理指令(包括#include指令)的初始序列,与在用-xpch=use指定的文件中预处理指令的序列相同.
要共享多个源文件间的预编译头文件,这些源文件就必须作为标记的初始序列共享包括文件的共同集合.
该标记的初始序列称为可用前缀.
可用前缀必须在使用相同预编译头文件的所有源文件中解释一致.
可用前缀以每个源文件的第一个标记开头,并以#pragmahdrstop或-xpchstop选项中命名的头文件的#include指令的最后一个标记结尾.
源文件的可用前缀只能包含注释和以下任意预处理程序指令:#include#if/ifdef/ifndef/else/elif/endif#define/undef#ident(如果相等,按原样传递)#pragma(如果相等)以上任何指令都可以引用宏.
#else、#elif和#endif指令必须在可用前缀内匹配.
在共享预编译头文件的每个文件的可用前缀中,每个相应的#define和#undef指令必须引用相同的符号(例如每个#define必须引用同一个值).
这些指令在每个可用前缀中出现的顺序也必须相同.
每个相应pragma也必须相同,且必须按相同顺序出现在共享预编译头文件的所有文件中.
17-114C++用户指南2004年4月融入预编译头文件的头文件一定不要违反以下约束.
这里没有定义对违反任意这些约束的程序的编译结果.
I头文件一定不要包含函数和变量定义.
I头文件一定不要使用__DATE__和__TIME__.
使用预处理宏会产生无法预料的结果.
I头文件一定不要包含#pragmahdrstop.
I头文件一定不要在可用前缀中使用__LINE__和__FILE__.
头文件可以在包括的头文件中使用__LINE__和__FILE__.
如何修改make文件以下是要将-xpch融入生成中而对make文件进行修改的几种可能方法.
I可以通过使用make和dmake的辅助CCFLAGS变量和KEEP_STATE功能来使用隐式make规则.
预编译头文件在独立的步骤中产生.
您还可以定义自己的编译规则,而无需尝试使用辅助CCFLAGS.
.
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.
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-c17-116C++用户指南2004年4月Q.
2.
148-xpg-xpg选项编译自身文件配置代码,为使用gprof的文件配置收集数据.
该选项调用运行时记录机制,该机制会在程序正常终止时生成gmon.
out文件.
警告如果在不同的步骤中编译和链接且使用了-xpg进行链接,就要确保使用-xpg进行链接.
另见-xprofile=p、analyzer(1)手册页、《程序性能分析工具》.
Q.
2.
149-xport64[=(v)]使用该选项可以帮助您调试移植到64位环境的代码.
具体来说,该选项会对以下情况提示警告信息:类型的截断(包括指针),符号扩展以及对位包装的更改.
将代码从诸如V7的32位体系结构移植到诸如V9的64位体系结构时,这些更改是很通常的.
值下表列出了v的有效值:缺省如果未指定-xport64,则缺省为-xport64=no.
如果指定了-xport64但不指定标志,则缺省为-xport64=full.
表Q-42-xport64值v的值含义no将代码从32位环境移植到64位环境时,不会生成与该代码移植有关的任何警告.
implicit只生成隐式转换的警告.
显式类型转换出现时不生成警告.
full将代码从32位环境移植到64位环境时,生成了与该代码移植有关的所有警告.
其中包括对64位值的截断警告、根据ISO值的保存规则对64位的符号扩展,以及对位字段包装的更改.
附录17C++编译器选项17-117示例本节提供了可以导致类型截断、符号扩展和对位包装更改的代码示例.

检查64位值的截断在移植到诸如V9的64位架构时,数据可能会被截断.
截断可能会因赋值(初始化时)或显式类型转换而隐式地发生.
两个指针的不同之处在于typedefptrdiff_t,它在32位模式下是32位整数类型,而在64位模式下是64位整数类型.
将较长的整数类型截断为较小的整型类型会生成警告,如下示例所示.
当显式转换导致数据截断时,请使用-xport64=implicit禁用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%example%CC-c-xarch=v9-Qoptionccfe-xport64=implicittest1.
c"test1.
c",line3:Warning:Conversionof64-bittypevalueto"int"causestruncation.
1Warning(s)detected.
example%17-118C++用户指南2004年4月在移植到64位架构过程中出现的另一个常见问题是指针的截断.
该问题在C++中始终是错误.
指定-xport64时,诸如将指针转换为引起这种截断的整型的操作,可能会在V9中导致错误诊断.
检查符号扩展您还可以使用-xport64选项来检查这种情况:标准ISOC值保留的规则允许在无符号整数类型的表达式中进行有符号整数值的符号扩展.
这种符号扩展会产生细微的运行时错误.
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%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.
附录17C++编译器选项17-119检查位字段包装的更改使用-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%17-120C++用户指南2004年4月警告注意,只有在64位模式下通过指定诸如-arch=generic64或-xarch=v9选项进行编译时才生成警告.
另见第17-68页的"-xarch=isa".
Q.
2.
150-xprefetch[=a[,a.
.
.
]]SPARC:在支持预取的架构上启用预取指令,这些架构包括UltraSPARCII(-xarch=v8plus、v8plusa、v9plusb、v9、v9a或v9b)a必须是下列值之一:使用-xprefetch,-xprefetch=auto和-xprefetch=yes,编译器就可以将预取指令自由插入到它生成的代码中.
该操作会提高支持预取的架构的性能.

如果正在较大的多处理器上运行计算密集的代码,您会发现使用-xprefetch=latx:factor有很多优点.
该选项指示代码生成器按照指定的因子调节在预取及其相关的装入或存储之间的缺省延迟时间.
预取延迟是执行预取指令和预取数据在缓存中可用时间之间的硬件延迟.
编译器决定放置使用预取数据的预取指令和装入或存储指令的距离时,假定预取延迟值.

注–在预取和装入之间假定的延迟可能与在预取和存储之间假定的延迟不同.

表Q-43-xprefetch值值含义auto启用预取指令的自动生成no%auto禁用预取指令的自动生成explicit启用显式预取宏no%explicit禁用显式预取宏latx:factor按照指定的因子调整编译器假定的预取到装入和预取到存储的延迟.
该因子必须是正浮点数或整数.
yes-xprefetch=yes与-xprefetch=auto,explicit相同no-xprefetch=no与-xprefetch=no%auto,no%explicit相同附录17C++编译器选项17-121编译器在多个机器和应用程序间调整预取机制以获得最佳性能.
这种调整并非总能达到最优.
对于内存密集的应用程序,尤其是要在较大的多处理器上运行的应用程序,您可以通过增加预取延迟值获得更高的性能.
要增加值,请使用大于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.
17-122C++用户指南2004年4月警告显式预取只应在度量支持的特殊环境下使用.
因为编译器在多个机器和应用程序之间调节预取机制以获得最优性能,所以当性能测试指示性能明显提高时,应该仅使用-xprefetch=latx:factor.
假定的预取延迟在不同发行版本中是不同的.
因此,无论何时切换到不同的发行版本,强烈建议重新测试延迟因子对性能的影响.
Q.
2.
151-xprefetch_level[=i]与使用-xprefetch=auto一样,使用新的-xprefetch_level=i选项来控制自动插入的预取指令的攻击性.
编译器更加主动,换句话说,引入了更多更高-xprefetch_level级别的预取.
-xprefetch_level的合适值取决于应用程序中缓存缺失的数量.
较高的-xprefetch_level值有可能提高具有大量缓存缺失的应用程序的性能.
值i必须是1、2或3之一.
缺省当指定-xprefetch=auto时,缺省为-xprefetch_level=2.
交互只有在支持预取的平台上(v8plus、v8plusa、v9、v9a、v9b、generic64、native64)并且使用-xprefetch=auto和3或更高的优化级别(-xO3)对该选项进行编译时该选项才有效.
表Q-44-xprefecth_level值值含义1启用预取指令的自动生成.
2超出-xprefetch_level=1目标的目标附加循环用于预取插入.
附加预取可以在-xprefetch_level=1插入的预取之外插入.
3超出-xprefetch_level=2目标的目标附加循环用于预取插入.
附加预取可以在-xprefetch_level=2插入的预取之外插入.
附录17C++编译器选项17-123Q.
2.
152-xprofile=p使用该选项要先收集并保存执行频率的数据,这样您才能使用随后运行的数据以提高性能.
只有将优化指定为-xO2或更高级别时,该选项才有效.
为编译器提供运行时的性能反馈增强了使用高优化级别(如-xO5)进行编译的效果.
为了生成运行时的性能反馈,就必须使用-xprofile=collect编译,然后运行不是典型数据集的可执行文件,最后用最高的优化级别并使用-xprofile=use重新编译.
对多线程应用程序来讲,配置文件集合是安全的.
也就是说,对执行自身多任务(-mt)的程序进行文件配置会产生准确的结果.
只有将优化指定为-xO2或更高级别时,该选项才有效.
值p必须是下列值之一:Icollect[:name]优化器使用-xprofile=use收集并保存执行频率,以便将来使用.
编译器生成测量语句执行频率的代码.
name是被分析的程序的名称.
name是可选的并(如果未为其指定名称)被假定为a.
out.
在运行时,使用-xprofile=collect:name编译的程序会创建子目录name.
profile来保存运行时的反馈信息.
数据将写入该子目录下的文件feedback中.
可以使用$SUN_PROFDATA和$SUN_PROFDATA_DIR环境变量来更改反馈信息的位置.
更多信息请参阅交互一节.
如果多次运行程序,那么执行频率数据会累积在feedback文件中,也就是说以前运行的输出不会丢失.
如果在不同的步骤中编译和链接,请确保使用-xprofile=collect编译的任何目标文件也使用-xprofile=collect进行链接.
Iuse[:name]使用生成并保存在feedback文件中的执行频率数据来优化程序,该数据由先前执行使用-xprofile=collect编译的程序生成并保存.
name是被分析的可执行文件的名称.
name是可选的并(如果未为其指定名称)被假定为a.
out.
除了从-xprofile=collect更改为-xprofile=use的-xprofile选项之外,源文件和其它编译器选项必须与用于编译的源文件和编译器选项完全相同,其中编译创建了依次生成feedback文件的编译程序.
编译器的相同版本必须既用于收集生成也用于使用生成.
如果使用-xprofile=collect:name编译,那么相同的程序名称name必须出现在优化的编译中:-xprofile=use:name.
17-124C++用户指南2004年4月在使用-xprofile=collect编译目标文件时,目标文件及其配置文件数据之间的关联取决于目标文件的UNIX路径名.
在某些情况下,编译器不将目标文件与其文件配置数据关联:由于先前没有用-xprofile=collect编译,所以该目标文件不包含文件配置数据,也不使用-xprofile=collect链接,该程序也决不会被执行.
如果先前使用了-xprofile=collect在不同目录中编译目标文件,并且该目标文件与使用-xprofile=collect编译的其它目标文件共享公共基名,但却无法通过它们包含的目录名称进行唯一的标识,那么编译器也会发生混淆.
在这种情况下,即使目标文件具有文件配置数据,使用-xprofile=use重新编译目标文件时,编译器也不能在反馈目录中找到该目标文件.
所有这些情况都能使编译器释放目标文件及其文件配置数据之间的关联.
因此,在您指定-xprofile=use时,如果目标文件具有文件配置数据但编译器无法将其与目标文件的路径名相关联,那么请使用-xprofile_pathmap选项来标识正确的目录.
请参阅第17-125页的"-xprofile_pathmap"Itcov使用新型的tcov进行基本块覆盖分析.
该选项是tcov的新型基本块文件配置.
该选项具有与-xa选项类似的功能,但可以为在头文件中具有源代码或使用C++模板的程序正确收集数据.
代码指令与-xa选项的代码指令类似,但不再生成.
d文件.
相反却生成单一文件,并且该文件的名称是按照最后的可执行文件命名的.
例如,如果程序在/foo/bar/myprog.
profile的外部运行,那么数据文件将存储到/foo/bar/myprog.
profile/myprog.
tcovd中.
在运行tcov时,必须将其传递给-x选项,以强制它使用新型数据.
如果不传递-x,则tcov使用缺省的旧式.
d文件并产生无法预料的输出.
与-xa选项不同,TCOVDIR环境变量在编译时无效.
不过,在程序运行时可以使用环境变量的值.
交互-xprofile=tcov和-xa选项在单一可执行文件中相互兼容.
也就是说,您可以链接程序,其中程序包含了用-xprofile=tcov编译过的某些文件以及用-xa编译的其它文件.
您不能同时用这两个选项来编译单一文件.
如果由于使用-xinline或-xO4才使函数内联,那么-xprofile=tcov生成的代码覆盖报告是不可靠的.
您可以设置环境变量$SUN_PROFDATA和$SUN_PROFDATA_DIR,来控制使用-xprofile=collect编译的程序放置文件配置数据的位置.
如果不设置这些变量,则文件配置数据会被写入当前目录中的name.
profile/feedback(name是可执行文件的名称或是在-xprofile=collect:name标志中指定的名称).
如果设置了这些变量,则-xprofile=collect数据会被写入到$SUN_PROFDATA_DIR/$SUN_PROFDATA.
附录17C++编译器选项17-125$SUN_PROFDATA和$SUN_PROFDATA_DIR环境变量类似地控制着用tcov编写的文件配置数据文件的路径和名称.
更多信息请参阅tcov(1)手册页.
警告如果在不同的步骤中编译和链接,-xprofile选项就必须出现在编译命令和链接命令中.
虽然在一个步骤中包括-xprofile并从其它步骤排除不会影响程序的正确性,但这样将无法进行文件配置.
另见-xa、tcov(1)手册页、《程序性能分析工具》.
Q.
2.
153-xprofile_ircache[=path]在use阶段,同时使用-xprofile_ircache[=path]和-xprofile=collect|use会重用collect阶段保存的编译数据,从而可以减少编译时间.
在编译大程序时,由于中间数据的保存,使得使用阶段的编译时间大大减少.
注意,所保存的数据会占用相当大的磁盘空间.
在使用-xprofile_ircache[=path]时,path会覆盖保存缓存文件的位置.
缺省情况下,这些文件会作为目标文件保存在同一目录下.
collect和use阶段出现在两个不同目录中时,指定路径才是有用的.
以下是命令的典型序列:Q.
2.
154-xprofile_pathmap当您还指定了-xprofile=use命令时,请使用-xprofile_pathmap=collect_prefix:use_prefix选项.
当以下两种情况都为真且编译器无法找到用-xprofile=use编译的目标文件的文件配置数据时,请使用-xprofile_pathmap.
I使用-xprofile=use编译目标文件所在的目录与先前使用-xprofile=collect编译目标文件所在的目录不同.
I目标文件会共享文件配置中的公共基名,但却可以根据它们在不同目录中的位置互相区分.
example%CC-xO5-xprofile=collect-xprofile_ircachet1.
cct2.
ccexample%a.
out//运行收集反馈数据example%CC-xO5-xprofile=use-xprofile_ircachet1.
cct2.
cc17-126C++用户指南2004年4月collect-prefix是目录树的UNIX路径名的前缀,在该目录树中使用-xprofile=collect编译目标文件.
use-prefix是目录树的UNIX路径名的前缀,在该目录树中使用-xprofile=use编译目标文件.
如果指定了-xprofile_pathmap的多个实例,那么编译器将按照这些实例出现的顺序对其进行处理.
在标识了匹配的use-prefix或发现最后指定的use-prefix与目标文件路径名不匹配之前,每个由-xprofile_pathmap的实例指定的use-prefix都会与目标文件路径名进行比较.
Q.
2.
155-xregs=r[,r.
.
.
]SPARC:控制临时寄存器的用法.
如果编译器可以使用更多的寄存器用于临时存储(临时寄存器),那么编译器将能生成速度更快的代码.
该选项使得附加的临时寄存器可用,这些寄存器并非总是适用.

值r必须是下列值之一:每个值的含义都取决于-xarch的设置.
缺省如果未指定-xregs,则假定-xregs=appl,float.
表Q-45-xregs值r的值含义[no%]appl[不]允许编译器生成将应用程序寄存器用为临时寄存器的代码.
应用程序寄存器是:g2,g3,g4(v8a,v8,v8plus,v8plusa,v8plusb)g2,g3(v9,v9a,v9b)强烈建议使用-xreg=no%appl编译所有系统软件和库.
系统软件(包括共享库)必须为应用程序保留这些寄存器值.
这些值的使用将由编译系统控制,而且在整个应用程序中必须保持一致.
关于SPARC指令集的更多信息请参阅第17-68页的"-xarch=isa".
在SPARCABI中,这些寄存器被描述为应用程序寄存器.
因为需要更少的load和store指令,所以使用这些寄存器可以提高性能.
不过,这样使用会与将寄存器用于其它目的的程序发生冲突.

[no%]float[不]允许编译器生成将浮点寄存器用为整数值的临时寄存器的代码.
使用浮点值可能会用到与该选项无关的这些寄存器.
如果使用-xregs=no%float,则源程序不能包含任何浮点代码.
附录17C++编译器选项17-127示例要使用所有可用的临时寄存器编译应用程序,请使用-xregs=appl,float.
要编译对相关切换敏感的非浮点代码,请使用-xregs=no%appl,no%float.
另见SPARCV7/V8ABI,SPARCV9ABIQ.
2.
156-xs允许在用dbx调试时不包括对象(.
o)文件.
该选项禁用了dbx的自动读取.
如果不能保存.
o文件,则请使用该选项.
该选项将-s选项传递给汇编程序.
不自动读取是装入符号表的较旧的方法.
该方法将dbx的所有符号表放置在可执行文件中.
因此,链接程序的链接和dbx的初始化会更加缓慢.
自动读取是装入符号表的较新的方法,同时也是缺省的方法.
使用自动读取时,信息被放置在.
o文件中,这样dbx就可以装入所需的符号表信息.
因此链接程序的链接以及dbx的初始化都更快速.
使用-xs时,如果将可执行文件移至另一目录,就不必通过移动对象(.
o)文件来使用dbx.
不使用-xs时,如果将可执行文件移至另一目录,就必须通过移动源文件和对象(.
o)文件来使用dbx.
Q.
2.
157-xsafe=memSPARC:允许编译器假定不违反内存保护.
该选项允许编译器使用SPARCV9架构中的无故障装入指令.
交互该选项只有与-xO5优化共同使用,且指定了-xarch=v8plus、v8plusa、v8plusb、v9、v9a或v9b时才有效.
17-128C++用户指南2004年4月警告因为错误(如地址未对齐或段违规)发生时无故障装入不产生自陷,所以该选项只能用于不发生这些错误的程序.
因为很少的程序会导致基于内存的自陷,所以您可以安全地将该选项用于大多数程序.
请不要将该选项用于显式依赖基于内存自陷的程序来处理异常情况.
Q.
2.
158-xsb该选项会使CC驱动程序为源码浏览器在SunWS_cache子目录中生成多余的符号表信息.
另见-xsbfastQ.
2.
159-xsbfast仅生成源码浏览器信息,而不进行编译.
该选项只运行ccfe阶段以在源码浏览器的SunWS_cache子目录中生成多余的符号表信息.
不生成任何目标文件.
另见-xsbQ.
2.
160-xspaceSPARC:不允许增加代码大小的优化.
Q.
2.
161-xtarget=t为指令集和优化指定目标平台.
附录17C++编译器选项17-129向编译器提供目标计算机硬件的准确描述有助于提高某些程序的性能.
当程序性能很重要时,目标硬件的正确说明会是非常重要的.
在较新的SPARC处理器上运行时这一点尤其重要.
不过,对多数程序和较旧的SPARC处理器来讲,性能的获取是可以忽略的,而通用说明已经足够了.
-xtarget的每个特定值都会扩展到-xarch、-xchip和-xcache选项值的特定集合.
使用fpversion(1)命令在运行的系统上决定-xtarget=native的扩展.
关于值的信息请参阅表Q-46.
例如,-xtarget=sun4/15等价于:-xarch=v8a-xchip=micro-xcache=2/16/1.
注–在该平台上进行编译时,特定主机平台的-xtarget扩展不能扩展到与-xtarget=native相同的-xarch、-xchip或-xcache设置上.
值对于SPARC平台:在SPARC平台上,t必须是下列值之一:表Q-46SPARC平台的-xtarget值t的值含义native在主机系统上获取最佳性能.
编译器生成为主机系统优化的代码.
它决定了运行编译器的计算机的可用架构、芯片和缓存属性.
native64在主机系统上获取64位对象二进制文件的最佳性能.
编译器生成为主机系统优化的64位对象二进制文件.
它决定了运行编译器的计算机的可用64位架构、芯片和缓存属性.
generic获取通用架构、芯片和缓存的最佳性能.
编译器将-xtarget=generic扩展到:-xarch=generic-xchip=generic-xcache=generic.
这是缺省值.
generic64在大多数64位平台架构上设置64位对象二进制文件的最佳性能的参数.
platform-name获取指定平台的最佳性能.
从表Q-47选择SPARC平台名称.
17-130C++用户指南2004年4月下表详细列出了-xtargetSPARC的平台名称及其扩展.
表Q-47-xtarget的SPARC平台名称-xtarget=-xarch-xchip-xcachegenericgenericgenericgenericcs6400v8plusasuper16/32/4:2048/64/1entr150v8plusaultra16/32/1:512/64/1entr2v8plusaultra16/32/1:512/64/1entr2/1170v8plusaultra16/32/1:512/64/1entr2/1200v8plusaultra16/32/1:512/64/1entr2/2170v8plusaultra16/32/1:512/64/1entr2/2200v8plusaultra16/32/1:512/64/1entr3000v8plusaultra16/32/1:512/64/1entr4000v8plusaultra16/32/1:512/64/1entr5000v8plusaultra16/32/1:512/64/1entr6000v8plusaultra16/32/1:512/64/1sc2000v8plusasuper16/32/4:2048/64/1solb5v7old128/32/1solb6v8super16/32/4:1024/32/1ss1v7old64/16/1ss10v8super16/32/4ss10/20v8super16/32/4ss10/30v8super16/32/4ss10/40v8super16/32/4ss10/402v8super16/32/4ss10/41v8super16/32/4:1024/32/1ss10/412v8super16/32/4:1024/32/1ss10/50v8super16/32/4ss10/51v8super16/32/4:1024/32/1ss10/512v8super16/32/4:1024/32/1ss10/514v8super16/32/4:1024/32/1ss10/61v8super16/32/4:1024/32/1ss10/612v8super16/32/4:1024/32/1附录17C++编译器选项17-131ss10/71v8super216/32/4:1024/32/1ss10/712v8super216/32/4:1024/32/1ss10/hs11v8hyper256/64/1ss10/hs12v8hyper256/64/1ss10/hs14v8hyper256/64/1ss10/hs21v8hyper256/64/1ss10/hs22v8hyper256/64/1ss1000v8super16/32/4:1024/32/1ss1plusv7old64/16/1ss2v7old64/32/1ss20v8super16/32/4:1024/32/1ss20/151v8hyper512/64/1ss20/152v8hyper512/64/1ss20/50v8super16/32/4ss20/502v8super16/32/4ss20/51v8super16/32/4:1024/32/1ss20/512v8super16/32/4:1024/32/1ss20/514v8super16/32/4:1024/32/1ss20/61v8super16/32/4:1024/32/1ss20/612v8super16/32/4:1024/32/1ss20/71v8super216/32/4:1024/32/1ss20/712v8super216/32/4:1024/32/1ss20/hs11v8hyper256/64/1ss20/hs12v8hyper256/64/1ss20/hs14v8hyper256/64/1ss20/hs21v8hyper256/64/1ss20/hs22v8hyper256/64/1ss2pv7powerup64/32/1ss4v8amicro28/16/1ss4/110v8amicro28/16/1表Q-47-xtarget的SPARC平台名称(续下)-xtarget=-xarch-xchip-xcache17-132C++用户指南2004年4月ss4/85v8amicro28/16/1ss5v8amicro28/16/1ss5/110v8amicro28/16/1ss5/85v8amicro28/16/1ss600/120v7old64/32/1ss600/140v7old64/32/1ss600/41v8super16/32/4:1024/32/1ss600/412v8super16/32/4:1024/32/1ss600/51v8super16/32/4:1024/32/1ss600/512v8super16/32/4:1024/32/1ss600/514v8super16/32/4:1024/32/1ss600/61v8super16/32/4:1024/32/1ss600/612v8super16/32/4:1024/32/1sselcv7old64/32/1ssipcv7old64/16/1ssipxv7old64/32/1sslcv8amicro2/16/1ssltv7old64/32/1sslxv8amicro2/16/1sslx2v8amicro28/16/1ssslcv7old64/16/1ssvygerv8amicro28/16/1sun4/110v7old2/16/1sun4/15v8amicro2/16/1sun4/150v7old2/16/1sun4/20v7old64/16/1sun4/25v7old64/32/1sun4/260v7old128/16/1sun4/280v7old128/16/1sun4/30v8amicro2/16/1表Q-47-xtarget的SPARC平台名称(续下)-xtarget=-xarch-xchip-xcache附录17C++编译器选项17-133sun4/330v7old128/16/1sun4/370v7old128/16/1sun4/390v7old128/16/1sun4/40v7old64/16/1sun4/470v7old128/32/1sun4/490v7old128/32/1sun4/50v7old64/32/1sun4/60v7old64/16/1sun4/630v7old64/32/1sun4/65v7old64/16/1sun4/670v7old64/32/1sun4/690v7old64/32/1sun4/75v7old64/32/1ultrav8plusaultra16/32/1:512/64/1ultra1/140v8plusaultra16/32/1:512/64/1ultra1/170v8plusaultra16/32/1:512/64/1ultra1/200v8plusaultra16/32/1:512/64/1ultra2v8plusaultra216/32/1:512/64/1ultra2/1170v8plusaultra16/32/1:512/64/1ultra2/1200v8plusaultra16/32/1:1024/64/1ultra2/1300v8plusaultra216/32/1:2048/64/1ultra2/2170v8plusaultra16/32/1:512/64/1ultra2/2200v8plusaultra16/32/1:1024/64/1ultra2/2300v8plusaultra216/32/1:2048/64/1ultra2ev8plusaultra2e16/32/1:256/64/4ultra2iv8plusaultra2i16/32/1:512/64/1ultra3v8plusaultra364/32/4:8192/512/1ultra3cuv8plusaultra3cu64/32/4:8192/512/2表Q-47-xtarget的SPARC平台名称(续下)-xtarget=-xarch-xchip-xcache17-134C++用户指南2004年4月对于IA平台:在IA平台上,t必须是下列值之一:下表列出了Intel架构的-xtarget值:缺省在SPARC和IA设备上,如果未指定-xtarget,则假定-xtarget=generic.
扩展-xtarget选项是一个宏,它允许出现在商业购买平台上的-xarch、-xchip和-xcache组合的快速简单的说明.
-xtarget的唯一含义位于它的扩展中.
示例-xtarget=sun4/15表示-xarch=v8a-xchip=micro-xcache=2/16/1.
表Q-48IA平台的-xtarget值t的值含义generic获取通用架构、芯片和缓存的最佳性能.
这是缺省值.
native在主机系统上获取最佳性能.
386指定编译器生成在Intel80386微处理器上获得最优性能的代码.
486指定编译器生成在Intel80486微处理器上获得最优性能的代码.
pentium指定编译器生成在Pentium微处理器上获得最优性能的代码.
pentium_pro指定编译器生成在PentiumPro微处理器上获得最优性能的代码.
表Q-49Intel架构上的-xtarget扩展-xtarget=-xarch-xchip-xcachegenericgenericgenericgeneric386386386generic486386486genericpentium386pentiumgenericpentium_propentium_propentium_progeneric附录17C++编译器选项17-135交互SPARCV9架构的编译通过-xarch=v9|v9a|v9b选项表示.
设置-xtarget=ultra或ultra2是不必要的或不足够的.
如果指定了-xtarget,则-xarch=v9、v9a或v9b选项必须出现在-xtarget之后.
例如:扩展到以下内容并将-xarch值还原到v8.
正确的方法是在-xtarget之后指定-xarch.
例如:警告在不同的步骤中编译和链接时,必须在编译步骤和链接步骤中使用相同的-xtarget设置.
Q.
2.
162-xthreadvar[=o](SPARC)指定-xthreadvar来控制线程局部变量的实现.
将该选项与__thread声明说明符配合使用,以利用编译器线程局部存储功能.
用__thread说明符声明线程变量之后,请指定-xthreadvar启用具有动态(共享)库中位置独立代码(非PIC代码)的线程局部存储.
关于如何使用__thread的更多信息,请参阅第4-3页的"线程局部存储".
值o必须是下列值之一:-xarch=v9-xtarget=ultra-xarch=v9-xarch=v8-xchip=ultra-xcache=16/32/1:512/64/1-xtarget=ultra-xarch=v9表Q-50-xthreadvar的值r的值含义[no%]dynamic[不]编译动态装入的变量.
使用-xthreadvar=no%dynamic时对线程变量访问明显加快,但是不能在动态库中使用目标文件.
也就是说,不能在可执行文件中使用目标文件.
17-136C++用户指南2004年4月缺省如果未指定-xthreadvar,则编译器所用的缺省取决于是否启用位置独立的代码.
如果启用了位置独立的代码,则选项被设置为-xthreadvar=dynamic.
如果禁用了位置独立的代码,则选项被设置为-xthreadvar=no%dynamic.
如果指定了-xthreadvar但未指定任何参数,则选项被设置为-xthreadvar=dynamic.
交互在Solaris软件的不同版本上使用线程变量需要命令行上的不同选项.
I在Solaris8软件中,使用__thread的对象必须使用-mt来编译,而且必须使用-mt-L/usr/lib/lwp-R/usr/lib/lwp进行链接.
I在Solaris9软件中,使用__thread的对象必须使用-mt来编译和链接.
警告如果动态库中存在非位置独立的代码,那么就必须指定-xthreadvar.
链接程序不支持在动态库中与非PIC代码等价的线程变量.
由于非PIC线程变量要快很多,所以它应该作为可执行文件的缺省设置.
另见-xcode,-KPIC,-KpicQ.
2.
163-xtime使CC驱动程序报告各种编译步骤的执行时间.
Q.
2.
164-xtrigraphs[={yes|no}]根据ISO/ANSIC标准的定义启用或禁用对三字母序列的识别.
如果源代码具有包含问号()的文字串(编译器将其解释为三字符序列),那么您可以使用-xtrigraph=no子选项关闭对三字符序列的识别.
附录17C++编译器选项17-137值您可以指定以下两个-xtrigraphs值的其中一个:缺省如果不在命令行上包括-xtrigraphs选项,则编译器假定-xtrigraphs=yes.
如果仅指定了-xtrigraphs,则编译器假定-xtrigraphs=yes.
示例请参考以下名为trigraphs_demo.
cc的示例源文件.
如果使用-xtrigraphs=yes编译该代码,则输出:如果使用-xtrigraphs=no编译该代码,则输出:表Q-51-xtrigraphs值值含义yes启用整个编译单元三字母序列的识别no禁用整个编译单元三字母序列的识别#includeintmain(){(void)printf(inastringappearsas()\n");return0;}example%CC-xtrigraphs=yestrigraphs_demo.
ccexample%a.
out()inastringappearsas(]example%CC-xtrigraphs=notrigraphs_demo.
ccexample%a.
out()inastringappearsas()17-138C++用户指南2004年4月另见关于三字母的信息,请参阅《C用户指南》一章中关于ANSI/ISOC的转换.
Q.
2.
165-xunroll=n启用在可能的场合下解开循环.
该选项指定编译器是否优化(解开)循环.
值当n为1时,建议编译器不要解开循环.
当n为大于1的整数时,-unroll=n使编译器解开循环的次数为n.
Q.
2.
166-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++标准定义了语法的含义,则缺省是可以更改的.
附录17C++编译器选项17-139示例以下示例显示了在引号中前置为U的字符串文字,还显示了指定-xustr的命令行.
警告不支持十六位的字符文字.
Q.
2.
167-xvis[={yes|no}](SPARC)在使用VIS指令集软件开发者工具包(VSDK)中定义的汇编语言模板时,可以使用-xvis=[yes|no]命令.
VIS指令集是SPARCv9指令集的扩展.
尽管UltraSPARC是64位处理器,但在很多情况下数据都限制在8位或16位范围内,特别是多媒体应用程序中.
VIS指令可以用一条指令处理4个16位数据,这个特性使得处理诸如图像、线性代数、信号处理、音频、视频以及网络等新媒体的应用程序的性能大大提高.
缺省缺省为-xvis=no.
指定-xvis等价于指定-xvis=yes.
另见关于VSDK的更多信息,请参阅http://www.
sun.
com/processors/vis/.
Q.
2.
168-xwe通过返回非零的退出状态,将所有警告转换成错误.
example%catfile.
ccconstunsignedshort*foo=U"foo";constunsignedshortbar[]=U"bar";constunsignedshort*fun(){returnU"fun"};example%CC-xustr=ascii_utf16_ushortfile.
cc-c17-140C++用户指南2004年4月Q.
2.
169-z[]arg链接编辑器选项.
更多信息请参阅ld(1)手册页和SolarisLinkerandLibrariesGuide.
18-1附录18Pragma本附录描述了C++编译器pragma.
pragma是编译器指令,允许您为编译器提供附加信息.
该信息可以更改您在其他情况下无法控制的编译详细信息.
例如,packpragma影响了结构内的数据布局.
编译器pragma也称为指令.
预处理程序关键字pragma是C++标准的一部分,但pragma的形式、内容和含义对每个编译器是不同的.
C++标准不定义任何pragma.
注–依赖于pragma的代码是不可移植的.
R.
1Pragma形式C++编译器pragma的各种形式如下所示:变量keyword表示特定的指令;a表示参数.
#pragmakeyword#pragmakeyword(a[,akeyword(a[,a#pragmasunkeyword18-2C++用户指南2004年4月R.
2Pragma参考本节描述了C++编译器能识别的pragma关键字.
Ialign使参数变量内存对齐到指定数目的字节,并覆盖缺省.
Idoes_not_read_global_data断言函数的指定列表不直接或间接读取全局数据.
Idoes_not_return向编译器断言,调用的指定函数不返回.
Idoes_not_write_global_data断言函数的指定列表不直接或间接写入全局数据.
Idump_macros提供关于在代码中使用宏的信息.
Iend_dumpmacros标记dump_macrospragma的结束.
Ifini将指定函数标记为完成函数.
Ihdrstop标识预编译头文件的可用源码前缀的结束.
Iident将指定字符串放置在可执行文件的.
comment部分.
Iinit将指定函数标记为初始化函数.
Ino_side_effect表示函数不更改任何持续状态.
Ipack(n)控制结构偏移的布局.
n的值为数字"0、1、2、4或8",指定了针对任何结构成员的最坏情况的对齐.
附录18Pragma18-3Irarely_called告知编译器很少调用指定的函数.
Ireturns_new_memory断言每个命名的函数返回新分配的内存的地址,并且该指针的别名与任何其它指针的别名不同.
Iunknown_control_flow指定了违反过程调用的通用控制流属性的例程列表.
Iweak定义弱符号绑定.
R.
2.
1#pragmaalign使用align使列出的变量内存与integer字节对齐,并覆盖缺省.
请遵循以下限制:Iinteger必须是大于1小于128且幂为2的整数,有效的值为:1、2、4、8、16、32、64和128.
Ivariable是全局或静态变量,但不可以是局部或类成员变量.
I如果指定的对齐比缺省小,就使用缺省.
IPragma行必须显示在所涉及的变量的声明之前,否则该行被忽略.
I在pragma行上涉及但不在下面pragma行的代码中声明的任何变量都被忽略.
以下示例中的变量是正确声明的.
#pragmaaligninteger(variable[,variable.
.
.
])#pragmaalign64(aninteger,astring,astruct)intaninteger;staticcharastring[256];structS{inta;char*b;}astruct;18-4C++用户指南2004年4月#pragmaalign在名称空间内部使用时,必须使用粉碎名称.
例如,以下代码中的#pragmaalign语句就是无效的.
要纠正该问题,请将#pragmaalign语句中的a、b和c用它们的粉碎名称替换.
R.
2.
2#pragmadoes_not_read_global_data该pragma断言了指定的例程不直接或间接读取全局数据.
允许对调用这些例程的代码进行更好的优化.
具体来讲,赋值语句或存储可以围绕这样的调用移动.
指定函数的原型被声明后,该pragma才可用.
如果全局访问的断言不为真,那么程序的行为就是未定义的.
如果函数名称被重载,那么会选择最近声明的函数.
R.
2.
3#pragmadoes_not_return该pragma向编译器断言,调用指定例程不会返回.
这样编译器可以执行与假定一致的优化.
例如,寄存器生命周期在允许更多优化的调用点终止.
如果指定的函数不返回,程序的行为就是未定义的.
如果函数名称被重载,那么会选择最近声明的函数.
namespacefoo{#pragmaalign8(a,b,c)staticchara;staticcharb;staticcharc;}#pragmadoes_not_read_global_data(funcname[,funcname])#pragmadoes_not_return(funcname[,funcname])附录18Pragma18-5指定函数的原型被声明后,该pragma才是可用的,如以下示例所示:R.
2.
4#pragmadoes_not_write_global_data该pragma断言了指定的例程列表不直接或间接写入全局数据.
允许对调用这些例程的代码进行更好的优化.
具体来讲,赋值语句或存储可以围绕这样的调用移动.

指定函数的原型被声明后,该pragma才可用.
如果全局访问的断言不为真,那么程序的行为就是未定义的.
如果函数名称被重载,那么会选择最近声明的函数.
R.
2.
5#pragmadumpmacros要查看宏在程序中如何工作时,请使用该pragma.
该pragma提供了诸如宏定义、取消定义和用法实例的信息,并按宏的处理顺序将输出打印到标准错误(stderr).
dumpmacrospragma在文件结束或遇到#pragmaend_dumpmacro后生效.
请参阅第18-6页的"#pragmaend_dumpmacros".
您可以用以下参数代替value:externvoidexit(int);#pragmadoes_not_return(exit)externvoid__assert(int);#pragmadoes_not_return(__assert)#pragmadoes_not_wrtie_global_data(funcname[,funcname])#pragmadumpmacros(value[,value.
.
.
])值含义defs打印所有宏定义undefs打印所有取消定义的宏use打印关于使用的宏的信息loc打印位置(路径名称和行号)以及defs、undefs和useconds打印在条件指令中使用的宏的信息sys打印系统头文件中所有宏的定义、取消定义和使用的信息18-6C++用户指南2004年4月注–子选项loc、conds和sys是defs、undefs和use选项的限定符.
loc、conds和sys本身并不会产生任何效果.
例如,#pragmadumpmacros=loc,conds,sys是无效的.
dumpmacrospragma与命令行选项具有相同的效果,不过pragma会覆盖命令行选项.
请参阅第17-81页的"-xdumpmacros[=value[,value.
.
.
]]".
dumpmacrospragma不嵌套,因此处理#pragmaend_dumpmacros时,以下代码行停止打印宏信息:dumpmacrospragma的效果是累积性的.
以下代码行具有和以下行相同的效果如果使用选项#pragmadumpmacros=use,no%loc,那么使用的每个宏名称仅打印一次.
如果使用选项#pragmadumpmacros=use,loc,那么每次使用宏时都打印位置和宏名称.
R.
2.
6#pragmaend_dumpmacros该pragma标记dumpmacrospragma的结束,并停止打印关于宏的信息.
如果dumpmacrospragma之后不使用end_dumpmacrospragma,那么dumpmacrospragma在文件结束之前继续生成输出.
#pragmadumpmacros(defs,undefs)#pragmadumpmacros(defs,undefs).
.
.
#pragmaend_dumpmacros#pragmadumpmacros(defs,undefs)#pragmadumpmacros(loc)#pragmadumpmacros(defs,undefs,loc)#pragmaend_dumpmacros附录18Pragma18-7R.
2.
7#pragmafini使用fini将identifier标记为完成函数.
这些函数应为void类型,不接受任何参数,并且当程序在程序控制下终止或从内存删除包含的共享对象时被调用.
和初始化函数一样,完成函数按链接编辑器处理的顺序执行.
在源文件中,#pragmafini中指定的函数在该文件中的静态析构函数之后执行.
在pragma中使用标识符之前,请先声明这些标识符.
R.
2.
8#pragmahdrstop将hdrstoppragma嵌入源文件头文件中以标识可用源码前缀的结束.
例如,考虑以下文件:可用源码前缀在c.
h处结束,因此可以在每个文件中的c.
h后插入#pragmahdrstop.
#pragmahdrstop只能显示在源文件(用CC命令指定)的可用前缀的结尾部分.
不在任何包括文件中指定#pragmahdrstop.
请参阅第17-112页的"-xpch=v"和第17-115页的"-xpchstop=file".
#pragmafini(identifier[,identifier.
.
.
])example%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"18-8C++用户指南2004年4月R.
2.
9#pragmaident使用ident将string放置在可执行文件的.
comment部分.
R.
2.
10#pragmainit使用init将identifier标记为初始化函数.
这些函数应为void类型,不接受任何参数,并且在执行开始构造程序内存映像时调用.
将共享对象带到内存中的操作时,在程序启动或某些动态装入操作(例如dlopen())期间,执行共享对象中的初始化函数.
调用到初始化函数的唯一顺序就是链接编辑器静态和动态处理该函数的顺序.

在源文件中,#pragmainit中指定的函数在该文件中的静态构造函数之后执行.
在pragma中使用标识符之前,请先声明这些标识符.
R.
2.
11#pragmano_side_effect使用no_side_effect以表示函数不更改任何持续状态.
Pragma声明了命名的函数不具有任何副作用.
这意味着函数将返回仅依赖于传递参数的结果.
此外,函数和后面的函数调用:I不读取或写入调用点的调用者中可视的程序状态的任何部分.
I不执行I/O.
I不更改调用点不可视程序状态的任何部分.
编译器执行优化时可以使用该信息.
如果函数具有副作用,执行调用该函数的程序的结果是未定义的.
name参数指定了当前转换单元内函数的名称.
Pragma必须与函数在相同的作用域,并且必须在函数声明之后出现.
pragma必须在函数定义之前.
#pragmaidentstring#pragmainit(identifier[,identifier.
.
.
])#pragmano_side_effect(name[,name.
.
.
])附录18Pragma18-9如果函数被重载,那么该pragma应用到最近定义的函数.
如果最近定义的函数不具有相同的标识符,那么程序出现错误.
R.
2.
12#pragmapack(n)使用pack以影响结构成员的包装.
如果存在,n就必须是0或幂为2的数.
不为0的值指示编译器,数据类型使用较小的n字节对齐和平台的自然对齐.
例如,以下指令使得定义在指令之后(和随后的pack指令之前)的所有结构成员对齐不严格超过2字节的边界,即使正常对齐是4或8字节边界.
n为0或省略时,成员对齐还原为自然对齐值.
如果n的值等于或大于平台上最严格的对齐时,指令具有自然对齐的效果.
下表显示了每个平台最严格的对齐.
pack指令应用到下一个pack指令之前的所有结构定义.
如果在具有不同包装的不同转换单元中定义了相同的结构,那么程序会因某种原因而失败.
具体来将,不应该在包括定义预编译库接口的头文件之前使用pack指令.
推荐用法是将pack指令放置在包装结构之前的程序代码中,并在结构之后放置#pragmapack().
#pragmapack([n])#pragmapack(2)表R-1平台上最严格的对齐平台最严格的对齐IA4SPARC通用、V7、V8、V8a、V8plus、V8plusa、V8plusb8SPARCV9、V9a、V9b1618-10C++用户指南2004年4月在SPARC平台上使用#pragmapack包装比类型的缺省对齐更紧密的对齐时,必须为程序的编译和链接指定-misalign选项.
下表显示了整型数据类型的存储大小和缺省对齐.
R.
2.
13#pragmararely_called该pragma提示编译器,指定的函数很少被调用.
这样编译器就可以在这种例程的调用点上执行配置文件反馈式优化,而无需配置文件收集阶段的重载.
因为该pragma只是建议,所以编译器不执行基于该pragma的任何优化.
如果函数名称被重载,那么会选择最近声明的函数.
只有声明指定的函数原型之后,#pragmararely_called预处理程序指令才是可用的.
以下是#pragmararely_called的示例:表R-2存储大小和缺省对齐字节数类型SPARCV8大小,对齐SPARCV9大小,对齐IA大小,对齐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)附录18Pragma18-11R.
2.
14#pragmareturns_new_memory该pragma断言了每个命名的函数返回新分配内存的地址,并且指针不具有到其它任何指针的别名.
该信息允许优化器更好地跟踪指针值并明确内存位置.
这样可以改善调度和管线操作.
如果该断言为假,那么执行调用该函数的程序的结果是未定义的.
name参数指定了当前转换单元内函数的名称.
Pragma必须与函数在相同的作用域,并且必须在函数声明之后出现.
pragma必须在函数定义之前.
如果函数被重载,那么该pragma应用到最近定义的函数.
如果最近定义的函数不具有相同的标识符,那么程序出现错误.
如果函数名称被重载,那么会选择最近声明的函数.
R.
2.
15#pragmaunknown_control_flow使用unknown_control_flow指定违反程序调用的通用控制流属性的例程列表.
例如,从对任何其它例程的任意调用可以遇到对setjmp()的调用后的语句.
该语句由对longjmp()的调用遇到.
因为这种例程使标准流程图分析无效,调用它们的例程不能安全地优化,所以要禁用优化器来编译这些例程.
如果函数名称被重载,那么会选择最近声明的函数.
R.
2.
16#pragmaweak使用weak定义弱全局符号.
该pragma主要在源文件中用于生成库.
链接程序在不能解决弱符号时不会发出警告.
#pragmareturns_new_memory(name[,name.
.
.
])#pragmaunknown_control_flow(name[,name.
.
.
])#pragmaweakname1[=name2]18-12C++用户指南2004年4月weakpragma可以用以下两种形式之一来指定符号:I字符串形式.
字符串必须是C++变量或函数的粉碎名称.
无效粉碎名称引用的行为是不可预测的.
后端可以或不可以产生无效粉碎名称引用的错误.
无论是否产生错误,使用无效粉碎名称时后端的行为都是不可预测的.
I标识符形式.
标识符必须是在编译单元中以前声明的C++函数的明确标识符.
标识符形式不能用于变量.
前端(ccfe)遇到无效的标识符引用时将会产生错误消息.
#pragmaweakname在形式#pragmaweakname中,指令生成了name弱符号.
如果链接程序没有找到name的符号定义,将不会出现错误消息,也不会出现符号的多个弱定义的错误消息.
链接程序仅执行第一个遇到的定义.
如果另一个编译单元具有函数或变量的强定义,那么name将链接到该函数或变量.
如果没有name的强定义,那么链接符号将具有值0.
以下指令将ping定义为弱符号.
如果链接程序无法找到名为ping的符号定义,那么不会生成任何错误消息.
#pragmaweakname1=name2在#pragmaweakname1=name2形式中,符号name1成为对name2的弱引用.
如果name1不在其它地方定义,那么name1将具有值name2.
如果name1在其它地方定义,那么链接程序使用该定义并忽略对name2的弱引用.
以下指令指示链接程序解决对bar的任何引用,前提是在程序中的任何位置定义它,否则解决对foo的引用.
在标识符形式中,name2必须在当前编译单元中声明和定义.
例如:#pragmaweakping#pragmaweakbar=fooexternvoidbar(int){.
.
.
}externvoid_bar(int);#pragmaweak_bar=bar附录18Pragma18-13使用字符串形式时,符号不需要预先声明.
如果以下示例中的_bar和bar都是extern"C",那么函数不需要声明.
不过,bar必须在相同的对象中定义.
重载函数使用标识符形式时,必须在pragma位置的作用域中正好有一个具有指定名称的函数.
尝试与重载函数一起使用#pragmaweak的标识符形式是错误的.
例如:要避免错误,请使用字符串形式,如以下示例所示.
更多信息请参阅SolarisLinkerandLibrariesGuide.
extern"C"voidbar(int){.
.
.
}#pragmaweak"_bar"="bar"intbar(int);floatbar(float);#pragmaweakbar//错误,不明确的函数名称intbar(int);floatbar(float);#pragmaweak"__1cDbar6Fi_i_"//使浮点bar(int)为弱符号18-14C++用户指南2004年4月术语表-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)和作用域.
另见类变量,实例变量,局部变量.
标志请参阅编译器选项.
捕获为了执行其它操作,而对诸如程序执行等操作的截获.
截获引起微处理器操作的临时中止,并将程序控制转交给另一个源.
术语表-2C++用户指南2004年4月成员函数是函数而非数据定义或类型定义的类元素.
重载将相同的名称赋予多个函数或运算符.
抽象方法不包含实现的方法.
抽象类包含一个或多个抽象方法并因此不能被实例化的类.
定义抽象类的目的是为了通过抽象方法的实现,使其它类可以扩展抽象类并使其具体化.
递增链接程序通过仅将更改后的.
o文件链接到前一个可执行文件来创建新的可执行文件的链接程序.
动态绑定在运行时函数调用到函数体的连接.
有虚函数时才需动态绑定.
也称为后续绑定,运行时绑定.
动态类型由具有不同声明类型的指针或引用访问的对象的实际类型.
动态类型转换将指针或引用从声明的类型转换到与引用到的动态类型一致的任何类型的安全方法.
多继承直接源于多个基类的派生类的继承.
多态引用到对象的指针或引用的动态类型与声明的指针或引用类型不同的能力.

多线程在单或多处理器系统上开发并行应用程序的软件技术.
二进制兼容性链接目标文件的能力,目标文件由某一个发行版本编译,而使用另一个不同发行版本的编译器.
方法在某些面向对象的语言中,成员函数的另外一个名称.
符号表示某些程序实体的名称或标签.
符号表程序编译时显示的所有标识符、程序中标识符的位置和属性的列表.
编译器使用该表来解释标识符的使用.
构造函数在创建类对象时编译器自动调用的特殊类成员函数,这样可以确保对象实例变量的初始化.
构造函数必须始终具有与该函数所属的类相同的名称.
请参阅析构函数.

关键字在编程语言中具有唯一含义,并且仅在与该语言相关的文档中使用的字.

函数多态请参阅函数重载.
函数模板允许编写可以稍后用作模型或模式的单一函数(用于编写相关函数)的机制.
函数原型描述函数与程序其它部分接口的声明.
函数重载将相同的名称但不同的参数类型和数字赋予不同的函数.
也称为函数多态.

后续绑定请参阅动态绑定.
基类请参阅继承.
继承面向对象编程的一个功能,使得程序员可以从现有类(基类)派生新的类(派生类).
有三种继承:公有、保护和私有.
术语表-3静态绑定在编译期间函数调用到函数体的连接.
也称为预先绑定.
局部变量在块内已知的数据项,但块外代码不可访问.
例如,在方法内定义的任何变量都是局部变量,在方法外部无法使用.
开关请参阅编译器选项.
类由命名的数据元素(可以是不同类型的数据元素)和可以用该数据元素执行的一组操作组成的用户定义数据类型.
类变量作为一个整体与特定类关联但与类的特定实例不关联的数据项.
类变量在类定义中定义.
类变量也称为静态字段.
另见实例变量.
类模板描述一组类或相关数据类型的模板.
类型符号使用方法的说明.
基本类型是integer和float.
所有其它类型都是从这些基本类型构造的,构造方法包括:将基本类型组合到数组或结构中,或增加修饰符(例如指针或常量属性).
链接程序连接目标代码和库以形成完整的可执行程序的工具.
幂等头文件属性,在一个转换单元中包括多次与包括一次具有相同效果.
名称重整在C++中,大量函数可以共享相同的名称,因此仅用名称并不能很好的区分不同的函数.
编译器通过名称重整解决了这个问题,即为函数创建由函数名称和参数的某种组合组成的唯一名称,从而实现类型安全的链接.
名称重整也称为名称装饰.

提速啦(24元/月)河南BGP云服务器活动 买一年送一年4核 4G 5M

提速啦的来历提速啦是 网站 本着“良心 便宜 稳定”的初衷 为小白用户避免被坑 由赣州王成璟网络科技有限公司旗下赣州提速啦网络科技有限公司运营 投资1000万人民币 在美国Cera 香港CTG 香港Cera 国内 杭州 宿迁 浙江 赣州 南昌 大连 辽宁 扬州 等地区建立数据中心 正规持有IDC ISP CDN 云牌照 公司。公司购买产品支持3天内退款 超过3天步退款政策。提速啦的市场定位提速啦主...

bgpto:日本独立服务器6.5折($120起),新加坡独立服务器7.5折($93起)

bgp.to在对日本东京的独立服务器进行6.5折终身优惠促销,低至$120/月;对新加坡独立服务器进行7.5折终身优惠促销,低至$93/月。所有服务器都是直连国内,速度上面相比欧洲、美国有明显的优势,特别适合建站、远程办公等多种用途。官方网站:https://www.bgp.to/dedicated.html主打日本(东京、大阪)、新加坡、香港(CN)、洛杉矶(US)的服务器业务!日本服务器CPU...

2021HawkHost老鹰主机黑色星期五虚拟主机低至3.5折 永久4.5折

老鹰主机HawkHost是个人比较喜欢的海外主机商,如果没有记错的话,大约2012年左右的时候算是比较早提供支付宝付款的主机商。当然这个主机商成立时间更早一些的,由于早期提供支付宝付款后,所以受众用户比较青睐,要知道我们早期购买海外主机是比较麻烦的,信用卡和PAYPAL还没有普及,大家可能只有银联和支付宝,很多人选择海外主机还需要代购。虽然如今很多人建站少了,而且大部分人都用云服务器。但是老鹰主机...

设置虚拟内存为你推荐
云主机租用我想租用云主机,请问下该如何操作?注册国际域名注册国际域名时的地址怎么填写?域名主机IDC(主机域名)是什么意思?域名购买在网上购买域名 会受骗吗asp虚拟空间asp视频聊天室系统支持虚拟空间虚拟主机试用哪儿的虚拟主机可以试用??沈阳虚拟主机有没有不限空间、不限流量的网站?厦门虚拟主机新手用什么虚拟主机好?中文域名什么是中文域名?新网域名新网域名怎么样
ip反查域名 3322动态域名注册 80vps java主机 便宜建站 国外bt evssl证书 vip购优惠 metalink 如何安装服务器系统 双12 空间首页登陆 空间登录首页 河南移动梦网 德讯 杭州电信宽带优惠 114dns 免费php空间 电信宽带测速软件 国外免费网盘 更多