2023年7月29日发(作者:)
so符号可见性_控制共享库的符号可见性:第2部分-IBMXLCC++V13编译器的⾼级知识...IBM XL C / C ++ V13编译器:可见性属性的⽀持在 ,我们了解了处理符号可见性的不同⽅法。 最重要的包括:GNU可见性属性扩展,IBMAIX®导出⽂件和GNU版本脚本。 GNU可见性可以使程序员从源代码级别控制符号的可见性,⽽⽤于链接的脚本对于从构建和发布步骤的⾓度来控制符号可见性可能更为有⽤。但是,随着⽤于AIX和Linux®V13编译器的XL C / C ++的发布,XL C / C ++编译器接受了GNU可见性扩展。 此外,诸如new pragma指令和new global编译器选项之类的实体也可以⽤于此⽬的。 在这⼀部分中,我们将重点更多放在可见性属性设置及其最终解决⽅案上。此外,我们可能会详细介绍AIX和Linux可见性设计之间的差异以及所实现的AIX可见性的兼容性。可见性属性说明符与GNU可见性属性扩展类似,对于XL C / C ++编译器,程序员可以通过属性说明符使⽤GNU属性语法来设置符号可见性。 清单1显⽰了函数和变量声明的⽰例。清单1.变量和函数的可见性说明符int __attribute__((visibility("hidden"))) m; // m is set as "hidden"void __attribute__((visibility("protected"))) fun(); // fun() is set as "protected"可见性属性的类型可以是default , hidden , protected或internal 。 这与我们在上⼀篇⽂章中介绍的GNU语法⼀致。 但是,在缺省值中,AIX和Linux实现之间存在细微的差异。 本⽂稍后将对此进⾏讨论。乍⼀看,可见性属性看起来很简单。 但是,在编程实践中,程序员可能会有更多问题。 例如,⼀个普遍提出的问题是关于具有不同可见性的同⼀符号的多重定义。 这对于处理不同的标头定义可能并不罕见,并且可能给程序员带来很多⿇烦。 从编译器的⾓度来看,此问题是由不完善的现实引起的,解决⽅案将更多地依赖于程序员⽅⾯。 但是,编译器确实提供了规则和便利来提供帮助。 XL C / C ++编译器将采⽤⾸次遇到的可见性属性。 并且,在处理其余部分(具有不同的可见性)时,会向程序员发出警告。 最后,编译器将忽略后者定义的可见性。 清单2提供了⼀个⽰例。清单2.为同⼀符号指定的不同可见性属性extern int __attribute__((visibility("hidden"))) m; // "m" is "hidden".int __attribute__((visibility("protected"))) m; // Compiler warning - "protected" is ignored.在此⽰例中, m⾸先定义为hidden 。 这意味着在动态链接期间,变量的符号将不可见。 但是,后⾯的代码将再次对其进⾏设置,但是在protected , 全局可见 。 编译器将发出警告,然后在处理代码时忽略protected属性。有关可见性的其他⼀些问题将涉及类型 。 在C ++编码中,程序员可能能够⾃⼰创建类型 。 程序员甚⾄可能想知道是否可以为此类类型指定可见性属性。 这是⼀个有趣的问题,因为在C编程中此类问题永远不会发⽣。 所有内置类型都不会⼲扰可见性属性。 但是,在C ++编程中,这不再是正确的。 在下⾯的清单中对此进⾏了演⽰。清单3.为类指定的可见性属性class __attribute__((visibility("hidden"))) T // class T has "hidden" visibility{public: static int gVal; // T::gVal is "hidden" void Dosth(); // T::Dosth() is "hidden"};
T t1; // t1 is "hidden".T __attribute__((visibility("internal"))) t2; // t2 has "internal" visibility.在清单3中,我们定义了具有hidden可见性的类T 在C ++代码中,程序员可以为类以及函数和对象定义可见性属性。 语法相同,但效果会有所不同。 在这⾥,我们可以假设类型T是hidden 。 后来,代码定义了两个T类型的对象: t1和t2 。 您可能会发现定义的t1没有任何可见性属性说明符。 因此, t1的可见性设置是从其类型直观地获得的。 并且,对于t2 ,代码将其定义为internal可见性。 这样的定义将在其类型T的可见性属性之前。 因此, t2的最终可见性是internal 。 这是基本规则。 但是,与对象相关联的实体(如成员函数和静态成员)的可见性由于不同的对象可见性定义⽽不会更改。 这意味着,在清单3中, T::gVal和T::Dosth()将具有T类定义的hidden可见性。 此外,这还意味着相同类型的对象( t1和t2 )仍然共享相同的功能表,⽆论为它们指定了什么可见性属性。 并且,如果程序员打算改变此类成员的可见性,例如以成员函数为例,则程序员需要直接为成员函数指定可见性属性。 清单4显⽰了如何将T::Dosth()的可见性属性更改为protected 。清单4.更改类成员的可见性属性class __attribute__((visibility("hidden"))) T // class T has "hidden" visibility{public: static int gVal; // T::gVal is "hidden" void __attribute__((visibility("protected"))) Dosth(); // T::Dosth() is now "protected"};
T t1; // t1 is "hidden".T __attribute__((visibility("internal"))) t2; // t2 has "internal" visibility.可见性属性也可以应⽤于联合,枚举,名称空间和模板。 名称空间上的可见性将类似于作⽤域或上下⽂中的类。 为命名空间指定了可见性属性时,该属性仅应⽤于作⽤域中包含的任何符号。 但是,与此同时,功能仅限于封闭的范围。 清单5显⽰了⼀个⽰例。清单5.命名空间的Visibility属性namespace std __attribute__((visibility("hidden"))) { void foo1() {}; // foo1() has "hidden" visibility.}namespace std { void foo2() {} // The visibility of foo2() is "default"/"unspecified".}在此⽰例中, foo1()被hidden 。 但是, foo2()不会是hidden符号。 这意味着,如果您在⽂件中定义了名称空间std的可见性,那么编写具有相同名称空间std另⼀个⽂件的程序员将不会受到影响。 结果,这样的设计可以潜在地避免跨代码块(具有相同名称空间)的可见性设置的污染。模板定义也同样有趣。 程序员可能总是对规则感到好奇,并且想知道当模板和type参数都具有可见性属性设置时如何设置可见性属性。 简⽽⾔之,如果主模板定义具有可见性,则该可见性将隐式传播到模板实例化。 否则,默认情况下,模板实例化的可见性与其模板参数相同。 有关⽰例,请参见清单6。清单6.命名空间的Visibility属性class __attribute__((visibility("internal"))) A {};template
发布者:admin,转转请注明出处:http://www.yc00.com/xiaochengxu/1690561087a369184.html
评论列表(0条)