警告:忽略'visibility'属性 - 符号可见性 - C ++ / gcc

时间:2014-09-24 20:17:00

标签: c++ gcc shared-libraries

相关主题: Why does const imply internal linkage in c++, when it doesn't in C?

我正在关注GCC visibility wiki以增加对共享库的可见性。

在我编译源文件时会生成警告

  

警告:'可见性'属性被忽略[-Wattributes]

这是我的代码:

// my_shared_lib.h
#if __GNUC__ >= 4
    #define DLL_API __attribute__((visibility("default")))
    #define DLL_LOCAL __attribute__((visibility("hidden")))
#else
    #define DLL_API 
    #define DLL_LOCAL
#endif
DLL_LOCAL const int my_local_var;

编译时会产生以下警告:

my_shared_lib.h: 'visibility' attribute ignored [-Wattributes]
DLL_LOCAL const int my_local_var;
               ^

这是整个建筑信息:

make all
Building file: ../src/my_shared_lib.cc
Invoking: Cross G++ Compiler
g++-mp-4.8 -O3 -Wall -c -fmessage-length=0 -std=c++11 -MMD -MP -MF"src/my_shared_lib.d" -MT"src/my_shared_lib.d" -o "src/my_shared_lib.o" "../src/my_shared_lib.cc"
my_shared_lib.h: 'visibility' attribute ignored [-Wattributes]
DLL_LOCAL const int my_local_var;
               ^
Finished building: ../src/my_shared_lib.cc

有谁能告诉我如何沉默这个警告以及为什么会发生这种警告?

是否因为const variable默认为hidden

PS。 我正在使用g ++ 4.8

1 个答案:

答案 0 :(得分:4)

您可以通过将-Wno-attributes传递给编辑来使警告静音。

警告正在发生,因为正如相关的问题和答案所提到的,C++ const对象自动具有内部链接,除非它们被明确标记为extern;即它们默认是隐藏的。理由是鼓励将这些const值按原样放入头文件中(即以const int x = value;形式)。如果它们在默认情况下是公开的,那么如果在多个.cpp.o文件中出现相同的变量,则会遇到多个链接问题,如果将它们放在.h中会发生这种情况没有本地链接规则的文件。

您还应该看到警告/错误:

my_shared_lib.h:...: error: uninitialized const 'my_local_var' [-fpermissive]

这是错误的变体,因为除非另有说明,否则const是隐式静态的。

你如何解决这个问题?

首先,在使用const时,在标题中正确使用C++,它是:

const int my_local_var = VALUE;

如果您在.hC代码中共享此C++个文件,那么您的选择是:

  1. 不要使它const - 这对于C代码实际上毫无意义,并阻止您完成在标头中声明并在.c文件中定义但不在在生成的.so
  2. 中公开
  3. 使用#define - 是的,它很难看,但这在语义上比使用const代码更准确,因为它可以防止您因错误的分配而意外更改值。
  4. 在.h中声明:
  5. ...

    DLL_LOCAL extern const int my_local_var;
    

    然后在.cc / .cpp文件中将其定义为:

     #include "my_shared_lib.h"
    
     const int my_local_var = 42;
    

    您需要在#include中添加,否则它不会获得extern,从而允许它在.o组成.so文件中进行链接没有在.so本身中公开它。

    所以我们(在Mac上,但前提是相同的):

    部首:

    $ cat wodge.h
    
    #define PRIVATE __attribute__((visibility("hidden")))
    #define PUBLIC __attribute__((visibility("default")))
    
    PRIVATE extern const int my_local_var;
    int do_with_x(int x);
    

    第一个C++档案:

    $ cat wodge.cc
    
    #include "wodge.h"
    
    int
    do_with_x(int y)
    {
        return my_local_var * y;
    }
    

    第二个C++文件 - 值的定义:

    $ cat wodge2.cc 
    #include "wodge.h"
    
    const int my_local_var = 42;
    

    编译并显示结果符号表:

    $ g++-4.8 -c -O3 -Wall -o wodge.o wodge.cc
    $ g++-4.8 -c -O3 -Wall -o wodge2.o wodge2.cc
    $ g++-4.8 -shared -o foo.dylib *.o
    $ nm foo.dylib
    0000000000000fb0 T __Z9do_with_xi
    0000000000000fbc s _my_local_var
                     U dyld_stub_binder