2014-09-24 67 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