相关主题: 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
答案 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;
如果您在.h
和C
代码中共享此C++
个文件,那么您的选择是:
const
- 这对于C
代码实际上毫无意义,并阻止您完成在标头中声明并在.c
文件中定义但不在在生成的.so
#define
- 是的,它很难看,但这在语义上比使用const
代码更准确,因为它可以防止您因错误的分配而意外更改值。...
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