Oracle Solaris Studio 12.2:C++ 用户指南

4.1 链接程序作用域

可使用下列声明说明符来协助约束外部符号的声明和定义。文件链接到共享库或可执行文件之前,静态归档或目标文件指定的作用域限制不会生效。尽管如此,编译器仍然可以执行显示链接程序作用域说明符的某些优化。

通过使用这些说明符,您不必再使用链接程序作用域的 mapfile。也可以通过在命令行上指定-xldscope 来控制变量作用域的缺省设置。

有关更多信息,请参见A.2.136 -xldscope={v}

表 4–1 链接程序作用域声明说明符

值 

含义 

__global

符号定义具有全局链接程序作用域,是限制最小的链接程序作用域。对符号的所有引用都绑定到定义符号的第一个动态装入模块中的定义。该链接程序作用域是外部符号的当前链接程序作用域。

__symbolic

符号定义具有符号链接程序作用域,其限制程度高于全局链接程序作用域。将对链接的动态装入模块内符号的所有引用绑定到模块内定义的符号。在模块外部,符号也显示为全局符号。该链接程序作用域对应于链接程序选项 -Bsymbolic。尽管不能将 -Bsymbolic 与 C++ 库一起使用,但可以使用 __symbolic 说明符,而不会引起问题。有关链接程序的更多信息,请参见 ld(1)。

__hidden

符号定义具有隐藏的链接程序作用域。隐藏链接程序作用域具有比符号和全局链接程序作用域更高的限制。将动态装入模块内的所有引用绑定到该模块内的定义。符号在模块外部是不可视的。

符号定义可以用更多限制的说明符来重新声明,但是不可以用较少限制的说明符重新声明。符号定义后,不可以用不同的说明符声明符号。

__global 是限制最少的作用域,__symbolic 是限制较多的作用域,而 __hidden 是限制最多的作用域。

因为虚函数的声明影响虚拟表的结构和解释,所以所有虚函数对包括类定义的所有编译单元必须是可视的。

可以将链接程序作用域说明符应用于结构、类和联合声明和定义中,因为 C++ 类可能要求生成隐式信息,如虚拟表和运行时类型信息。在这种情况下,说明符后跟结构、类或联合关键字。这种应用程序为其所有隐式成员隐含了相同的链接程序作用域。

4.1.1 与 Microsoft Windows 兼容

为了在动态库方面与 Microsoft Visual C++ (MSVC++) 中的相似作用域功能兼容,也支持以下语法:

__declspec(dllexport) 等效于 __symbolic

__declspec(dllimport) 等效于 __global

在 Solaris Studio C++ 中使用此语法时,应将选项 -xldscope=hidden 添加到 CC 命令行。结果与使用 MSVC++ 得到的结果相当。在 MSVC++ 中,__declspec(dllimport) 应当仅用于外部符号的声明,而不用于定义。示例:


__declspec(dllimport) int foo(); // OK 
__declspec(dllimport) int bar() { ... } // not OK  

在 MSVC++ 中,对于将 dllimport 用于定义没有严格规定,而使用 Solaris Studio C++ 时结果则不同。尤其是,使用 Solaris Studio C++ 时将 dllimport 用于定义得到的是具有全局链接的符号而不是符号链接。Microsoft Windows 上的动态库不支持符号的全局链接。如果遇到此问题,可以更改源代码,对定义使用 dllexport 而不是 dllimport。这样,使用 MSVC++ 和使用 Solaris Studio C++ 得到的结果相同。