Charles Chow
Charles Chow

Reputation: 615

warning: 'visibility' attribute ignored - symbol visibility - C++/gcc

Related topic: Why does const imply internal linkage in c++, when it doesn't in C?

I was following GCC visibility wiki to add visibility to my shared library.

It generates a warning when I'm compiling my source file

warning: 'visibility' attribute ignored [-Wattributes]

Here's my code:

// 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;

It generate following warning while compiling:

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

Here's the entire building message:

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

Can anyone tell me how to silent this warning and why this warning happened?

Is it because const variable are hidden by default?

PS. I'm using g++ 4.8

Upvotes: 9

Views: 17569

Answers (1)

Anya Shenanigans
Anya Shenanigans

Reputation: 94614

You can silence the warning by passing -Wno-attributes to the compilation.

The warning is happening because, as the related question and answer mentions, in C++ const objects automatically have internal linkage unless they're explicitly marked as extern; i.e. they're hidden by default. The rationale is to encourage putting these const values into header files as-is (i.e. in the form const int x = value;). If they were public by default, then you would suffer multiple-linkage issues if the same variable appeared across multiple .cpp or .o files, which is what would happen if they were placed in .h files without the local linkage rule.

You should also be seeing a warning/error:

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

which is a variation of the error because the const is implicitly static unless otherwise mentioned.

How do you fix this?

Firstly, use the const properly in the header when using C++, it's:

const int my_local_var = VALUE;

If you're sharing this .h file amongst C and C++ code then your choices are:

  1. Don't make it const - that's actually meaningless for the C code, and prevents you from accomplishing the private, declared in the header and defined in a .c file but not exposed in the resulting .so
  2. Use a #define - yes, it's ugly, but this is more semantically correct than using a const for C code as it prevents you from accidentally changing the value by erroneous assignment.
  3. declare it in the .h as:

...

DLL_LOCAL extern const int my_local_var;

and then define it in the .cc/.cpp file as:

 #include "my_shared_lib.h"

 const int my_local_var = 42;

You need to add in the #include or else it doesn't get the extern which allows it to be exposed for linking in the .o files that make up the .so without getting it exposed in the .so itself.

and so we have (on a mac, but the premise is the same):

Header:

$ 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);

First C++ file:

$ cat wodge.cc

#include "wodge.h"

int
do_with_x(int y)
{
    return my_local_var * y;
}

Second C++ file - definition of value:

$ cat wodge2.cc 
#include "wodge.h"

const int my_local_var = 42;

Compile and show the resulting symbol table:

$ 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

Upvotes: 9

Related Questions