c++ - __attribute__ ((weak)) 的处理在 clang 和 gcc 中是不同的

标签 c++ macos gcc clang

我有一个应用程序 (app) 和一个动态库/共享对象 (dlib),它们都链接到一个静态库,该静态库使用 __declspec (selectany) 在头文件中声明了一个全局变量 (gvar) |/__attribute__ ((weak)) .通过设计,app 和 dlib 都应该有自己的 gvar 拷贝(在 MSVC 和 GCC 上我完全明白这一点)。

移植到 Mac OSX 并用 clang 编译后,我看到 dlib 中的 gvar 链接到应用程序中的 gvar。不确定这是一个 clang 错误还是设计使然;如果是设计使然,是否有任何方法可以避免它并获得与 GCC/MSVC 中相同的行为?

clang 版本:

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

重现问题的最小项目:

主要.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 ();
}

共享.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);
}

构建.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

请注意,如果我删除 attribute ((weak)),则 app 和 dlib 会获得它们自己的 gvar 拷贝。

最佳答案

我在这里找到了答案: https://gcc.gnu.org/wiki/Visibility

为了获得我想要的行为,我必须将 -fvisibility=hidden 添加到命令行并将 __attribute__ ((visibility ("default"))) 添加到需要导出的符号。

关于c++ - __attribute__ ((weak)) 的处理在 clang 和 gcc 中是不同的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33751909/

相关文章:

c - 为什么 -fpie 在裸机代码中不起作用并导致野指针?

linux - 通过 LFS 7.5 构建 iso 时缺少 gd.h header 错误

c++ - boost::asio 充满了警告

c++ - 检查引用上的静态转换

c++ - 使用Qt线程的困惑

cocoa - 在 Mac 应用程序中启动新窗口

java - Apple 弃用 Java,我们作为程序员的技术选择是什么?

macos - OSX 10.10.1 上的文件系统区分大小写不匹配(Android Studio 和 IntelliJIDEA)

c++ - 将 std::bind 与 std::reference_wrapper::get 一起使用

c++ - C++ 编程的文件夹结构