2014-09-24 244 views
0

相关主题: Why does const imply internal linkage in c++, when it doesn't in C?警告: '知名度' 属性被忽略 - 符号可见 - C++/GCC

我下面GCC visibility wiki能见度添加到我的共享库。

它,当我编译我的源文件生成一个警告

warning: 'visibility' attribute ignored [-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

您可以通过将-Wno-attributes传递给编译来使警告消失。

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

你也应该看到一个警告/错误:

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

这是错误的变化,因为,除非另有提到的常量是隐式静态的。

你如何解决这个问题?

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

const int my_local_var = VALUE; 

如果要共享该.h文件当中CC++代码,那么你的选择是:

  1. 不要让它const - 这对C代码实际上是没有意义的,并且阻止你完成在头文件中声明并在一个.c文件,但不暴露在导致.so
  2. 使用#define - 是的,这是丑陋的,但是这是比使用const的C代码,因为它可以防止无意改变由错误的分配值更语义正确。
  3. 声明它的.H为:

...

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 
+0

非常详细的解答!谢谢! – 2014-09-24 23:46:44

+0

我相信这也适用于'静态' – EdH 2015-04-06 00:37:02