c – 处理__attribute __((弱))在clang和gcc中是不同的

我有一个应用程序(app)和一个动态库/共享对象(dlib),它们都链接到一个静态库,它使用__declspec(selectany)/ __attribute __((weak))在头文件中声明一个全局变量(gvar).根据设计,app和dlib都应该拥有自己的gvar副本(在MSVC和GCC上,我得到的确如此).

移植到Mac OSX并使用clang进行编译后,我发现dlib中的gvar链接到app中的gvar.不确定这是一个铿锵的bug还是设计;如果它是设计的,有没有办法避免它并获得与GCC / MSVC相同的行为?

铿锵版:

bash-3.2$c++ --version
Apple LLVM version 7.0.0 (clang-700.1.76)
Target: x86_64-apple-darwin15.0.0
Thread model: posix

重现问题的最小项目:

main.cpp中:

#include <stdio.h>
#include <dlfcn.h>

__attribute__ ((weak)) int g_global = 10;

int main ()
{
    printf ("main (): g_global: addr = %p; value = %d\n", &g_global, g_global);

    typedef void Foo ();

    void* so = dlopen ("./my-so.so", RTLD_LAZY | RTLD_LOCAL);
    Foo* foo = (Foo*) dlsym (so, "foo");
    foo ();
}

shared.cpp:

#include <stdio.h>

__attribute__ ((weak)) int g_global = 20;

extern "C" void foo ()
{
    printf ("foo (): g_global: addr = %p; value = %d\n", &g_global, g_global);
}

build.sh:

#!/bin/bash

rm -f my-so.so
rm -f app.

c++ -shared -fPIC shared.cpp -omy-so.so
c++ main.cpp -oapp -ldl

输出:

bash-3.2$./app
main (): g_global: addr = 0x10c657030; value = 10
foo (): g_global: addr = 0x10c657030; value = 10

请注意,如果我删除属性((弱)),那么app和dlib将获得自己的gvar副本.

最佳答案 我在这里找到了答案:

https://gcc.gnu.org/wiki/Visibility

为了获得我想要的行为,我不得不在命令行中添加-fvisibility = hidden并将属性((visibility(“default”))添加到需要导出的符号中.

点赞