海湾合作委员会:在什么样的方式内部可见性“在现实世界中相当无用”? [英] GCC: In what way is visibility internal "pretty useless in real world usage"?

查看:179
本文介绍了海湾合作委员会:在什么样的方式内部可见性“在现实世界中相当无用”?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个使用GCC的QNX(x86)库,我想制作一些在库中专门用于其他模块的符号,特别是使用该库的代码。



这个工作已经有了,但是在进行研究如何实现的时候,我在GCC的文档中发现了一个非常令人担忧的段落(参见 http://gcc.gnu.org/onlinedocs/gcc-4.8.2 /gcc/Code-Gen-Options.html#Code-Gen-Options ,标志-fvisibility的说明):


尽管命名,默认总是意味着公开;即可以从共享对象之外链接的
。保护和
内部在现实世界的使用是相当无用的,所以唯一的其他
常用的选项是隐藏的。如果-fvisibility不是
,则默认为默认值,即将每个符号公开 - 这将导致
与以前版本的GCC相同。


我非常感兴趣的是内部在现实世界中是如此无用。从我从GCC文档的另一段话中了解到的内容( http://gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/Function-Attributes.html#Function-Attributes ,可见性属性的说明),可见性internal是更强大(对我来说更有用)比可见度隐藏:


内部可见性就像隐藏的可见性,但额外的
处理器特定语义除非psABI另有规定,否则
GCC定义内部可见性,意味着从另一个模块调用的函数从不是
。与隐藏的函数进行比较,
,而不能被其他模块直接引用,可以通过函数指针间接引用
。通过指示一个
函数不能从模块外部调用,GCC可以为
实例省略PIC寄存器的负载,因为已知
调用函数加载了正确的值。 / p>

有人可以深入解释吗?



提前非常感谢!

解决方案

如果您只想隐藏内部符号,只需使用 -fvisibility = hidden 。它完全符合您的要求。



内部标志远远超过隐藏标志。它告诉编译器ABI兼容性并不重要,因为模块之外的任何人都不会使用该功能。如果一些外部代码确实会调用该函数,那么它可能会崩溃。



不幸的是,有很多方法意外暴露 internal 函数到外界,包括函数指针和C ++虚拟方法。例如,很多图书馆使用回调来表示事件。如果您的程序使用这些库之一,则绝对不要使用内部函数作为回调。如果这样做,编译器和链接器不会发生任何错误,您的程序将具有微妙的,难以调试的崩溃错误。



即使您的程序没有现在不要使用函数指针,当每个人(包括你)都忘记了这个限制时,它可能开始使用它们几年的道路。对于微小的性能提升而牺牲安全性通常是一个坏主意,因此内部可见性不是推荐的项目范围的默认值。



如果您尝试优化一些使用量很大的代码,则内部可见性更有用。您可以使用 __ attribute__((visibility(internal)))标记这些特定功能,这告诉编译器速度比兼容性更重要。你也应该为自己留下评论,所以你记得永远不要指点这些功能。


I am currently developing a library for QNX (x86) using GCC, and I want to make some symbols which are used exclusively in the library invisible to other modules, notably to the code which uses the library.

This works already, but, while doing the research how to achieve it, I have found a very worrying passage in GCC's documentation (see http://gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/Code-Gen-Options.html#Code-Gen-Options, explanation for flag -fvisibility):

Despite the nomenclature, default always means public; i.e., available to be linked against from outside the shared object. protected and internal are pretty useless in real-world usage so the only other commonly used option is hidden. The default if -fvisibility isn't specified is default, i.e., make every symbol public—this causes the same behavior as previous versions of GCC.

I am very interested in how visibility "internal" is pretty useless in real-world-usage. From what I have understood from another passage from GCC's documentation (http://gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/Function-Attributes.html#Function-Attributes, explanation of the visibility attribute), visibility "internal" is even stronger (more useful for me) than visibility "hidden":

Internal visibility is like hidden visibility, but with additional processor specific semantics. Unless otherwise specified by the psABI, GCC defines internal visibility to mean that a function is never called from another module. Compare this with hidden functions which, while they cannot be referenced directly by other modules, can be referenced indirectly via function pointers. By indicating that a function cannot be called from outside the module, GCC may for instance omit the load of a PIC register since it is known that the calling function loaded the correct value.

Could anybody explain in depth?

Thank you very much in advance!

解决方案

If you just want to hide your internal symbols, just use -fvisibility=hidden. It does exactly what you want.

The internal flag goes much further than the hidden flag. It tells the compiler that ABI compatibility isn't important, since nobody outside the module will ever use the function. If some outside code does manage to call the function, it will probably crash.

Unfortunately, there are plenty of ways to accidentally expose internal functions to the outside world, including function pointers and C++ virtual methods. Plenty of libraries use callbacks to signal events, for example. If your program uses one of these libraries, you must never use an internal function as the callback. If you do, the compiler and linker won't notice anything wrong, and your program will have subtle, hard-to-debug crash bugs.

Even if your program doesn't use function pointers now, it might start using them years down the road when everyone (including you) has forgotten about this restriction. Sacrificing safety for tiny performance gains is usually a bad idea, so internal visibility is not a recommended project-wide default.

The internal visibility is more useful if you have some heavily-used code that you are trying to optimize. You can mark those few specific functions with __attribute__ ((visibility ("internal"))), which tells the compiler that speed is more important than compatibility. You should also leave a comment for yourself, so you remember to never take a pointer to these functions.

这篇关于海湾合作委员会:在什么样的方式内部可见性“在现实世界中相当无用”?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆