Cha*_*how 4 c++ gcc shared-libraries
相关主题: 为什么const在C ++中表示内部链接而在C ++中却没有?
我正在关注GCC可见性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;
Run Code Online (Sandbox Code Playgroud)
编译时会产生以下警告:
my_shared_lib.h: 'visibility' attribute ignored [-Wattributes]
DLL_LOCAL const int my_local_var;
^
Run Code Online (Sandbox Code Playgroud)
这是整个建筑物的信息:
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
Run Code Online (Sandbox Code Playgroud)
谁能告诉我如何使此警告静音以及为什么发生此警告?
是不是因为const variable是hidden默认?
PS。我正在使用g ++ 4.8
您可以通过传递-Wno-attributes给编译来静默警告。
该警告之所以发生是因为,正如相关的问题和答案所提到的那样,C++除非const对象被明确标记为extern,否则它们会自动具有内部链接。即默认情况下它们是隐藏的。这样做的理由是鼓励将这些const值按原样(即以形式const int x = value;)放入头文件中。如果默认情况下它们是公共的,那么如果在多个文件.cpp或.o文件中出现相同的变量,您将遭受多重链接问题,如果将它们放置在.h没有本地链接规则的文件中会发生这种情况。
您还应该看到警告/错误:
my_shared_lib.h:...: error: uninitialized const 'my_local_var' [-fpermissive]
Run Code Online (Sandbox Code Playgroud)
除非另有说明,否则这是错误的一种变化,因为const是隐式静态的。
您如何解决这个问题?
首先,使用const时,请在标头中正确使用C++:
const int my_local_var = VALUE;
Run Code Online (Sandbox Code Playgroud)
如果要.h在C和C++代码之间共享此文件,则选择是:
const-这实际上对C代码没有意义,并且会阻止您完成私有,在标头中声明并在.c文件中定义但不会在结果中暴露.so#define-是的,这很丑陋,但这比使用constfor C代码在语义上更正确,因为它可以防止您因错误赋值而意外更改值。...
DLL_LOCAL extern const int my_local_var;
Run Code Online (Sandbox Code Playgroud)
然后在.cc/ .cpp文件中将其定义为:
#include "my_shared_lib.h"
const int my_local_var = 42;
Run Code Online (Sandbox Code Playgroud)
您需要添加,#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);
Run Code Online (Sandbox Code Playgroud)
第一个C++档案:
$ cat wodge.cc
#include "wodge.h"
int
do_with_x(int y)
{
return my_local_var * y;
}
Run Code Online (Sandbox Code Playgroud)
第二个C++文件-值的定义:
$ cat wodge2.cc
#include "wodge.h"
const int my_local_var = 42;
Run Code Online (Sandbox Code Playgroud)
编译并显示结果符号表:
$ 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
Run Code Online (Sandbox Code Playgroud)