小编Var*_*gaD的帖子

符号可见性,异常,运行时错误

我试着更好地理解符号可见性.GCC Wiki(http://gcc.gnu.org/wiki/Visibility)有一节关于"C++异常问题".根据GCC Wiki,由于没有导出的异常,可能会出现运行时错误.没有编译时错误/警告的运行时错误是非常危险的,所以我试图更好地理解问题.我做了一些实验,但我仍然无法重现它.任何想法如何重现问题?

Wiki提到了三个库互相使用,所以我创建了三个小库.

我运行以下命令:

没有vtable的异常类(按预期工作):

make
./dsouser
Run Code Online (Sandbox Code Playgroud)

使用vtable的异常类但它不会导出(甚至不编译):

make HAS_VIRTUAL=1
Run Code Online (Sandbox Code Playgroud)

异常类导出vtable(按预期工作):

make HAS_VIRTUAL=1 EXCEPTION_VISIBLE=1
./dsouser
Run Code Online (Sandbox Code Playgroud)

Makefile文件:

CXX=g++-4.7.1
CFLAGS=-ggdb -O0 -fvisibility=hidden
ifdef EXCEPTION_VISIBLE
  CFLAGS+=-DEXCEPTION_VISIBLE
endif
ifdef HAS_VIRTUAL
  CFLAGS+=-DHAS_VIRTUAL
endif
all: dsouser

libmydso.so: mydso.cpp mydso.h
    $(CXX) $(CFLAGS) -fPIC -shared -Wl,-soname,$@ -o $@ $<

libmydso2.so: mydso2.cpp mydso.h mydso2.h libmydso.so
    $(CXX) $(CFLAGS) -L.  -fPIC -shared -Wl,-soname,$@ -o $@ $< -lmydso

libmydso3.so: mydso3.cpp mydso.h mydso2.h mydso3.h libmydso2.so
    $(CXX) $(CFLAGS) -L.  -fPIC -shared -Wl,-soname,$@ -o $@ $< -lmydso -lmydso2

dsouser: dsouser.cpp …
Run Code Online (Sandbox Code Playgroud)

c++ visibility symbols exception elf

20
推荐指数
1
解决办法
2767
查看次数

符号可见性和命名空间

我正在Linux和gcc上尝试C++符号可见性.似乎首选的方法是使用-fvisibility = hidden,并根据Visibility gcc wiki页面(http://gcc.gnu.org/wiki/Visibility)逐个导出使用过的符号.我的问题是很多库都没有很好地处理这个问题,他们忘了明确导出符号,这是一个严重的问题.经过几次修复后,甚至某些部分的升压仍可能受到影响.当然,这些错误应该是固定的,但在此之前我想用一种"安全"的方式尽可能地隐藏符号.

我提出了一个解决方案:我将所有符号放在命名空间中,然后使用符号隐藏属性并导出公共接口,这样只会影响我的符号.

问题是,当我针对每个未导出的类编译针对该库的内容时,我收到了警告消息,并且我在应用程序中将其用作类字段.

namespace MyDSO __attribute__ ((visibility ("hidden"))) {
  struct Foo {
    void bar() __attribute__ ((visibility ("default"))) {}
  };
}

struct Bar {
  MyDSO::Foo foo;
};

int main() {}
Run Code Online (Sandbox Code Playgroud)

警告消息可以在这个小例子中重现,但当然命名空间应该在应用程序中的另一个类的库中.

$ gcc-4.7.1 namespace.cpp -o namespace
namespace.cpp:7:8: warning: ‘Bar’ declared with greater visibility than the type of its field ‘Bar::foo’ [-Wattributes]
Run Code Online (Sandbox Code Playgroud)

由于我理解符号可见性,隐藏命名空间应该与使用-fvisibility = hidden具有非常相似的效果,但我从未使用后者获得类似的警告.我看到当我将-fvisibility = hidden传递给应用程序时,应用程序中的类也将被隐藏,所以我不会收到警告.但是当我没有通过选项时,标题中的符号似乎都不会被编译器隐藏,所以我不会再收到警告.

这条警告信息的建议是什么?这是一个严重的问题吗?在哪种情况下会导致任何问题?如何隐藏命名空间与fvisibility = hidden不同?

c++ gcc visibility symbols

12
推荐指数
1
解决办法
2万
查看次数

标签 统计

c++ ×2

symbols ×2

visibility ×2

elf ×1

exception ×1

gcc ×1