Types of visibility attributes (IBM extension)

The following table describes different visibility attributes.
Table 1. Visibility attributes
Attribute Description
default Indicates that external linkage entities have the default attribute in object files. These entities are exported in shared libraries, and can be preempted.
protected Indicates that external linkage entities have the protected attribute in object files. These entities are exported in shared libraries, but cannot be preempted.
hidden Indicates that external linkage entities have the hidden attribute in object files. These entities are not exported in shared libraries, but their addresses can be referenced indirectly through pointers.
internal Indicates that external linkage entities have the internal attribute in object files. These entities are not exported in shared libraries, and their addresses are not available to other modules in shared libraries.
Notes:
  • In this release, the hidden and internal visibility attributes are the same. The addresses of the entities that are specified with either of these visibility attributes can be referenced indirectly through pointers.
  • On the AIX® platform, all the external linkage entities do not have visibility attributes by default if they do not get visibility attributes from the compiler option, pragma directives, explicitly specified attributes, or propagation rules. Whether these entities are exported in shared libraries depends on the specified export list or the one that is generated by the compiler.
  • On the AIX platform, entity preemption occurs only when runtime linking is used. For details, see Linking a library to an application.

Example:  Differences among the default, protected, hidden, and internal
visibility attributes

//a.c
#include <stdio.h>
void __attribute__((visibility("default"))) func1(){
   printf("func1 in the shared library");
}
void __attribute__((visibility("protected"))) func2(){
   printf("func2 in the shared library");
}
void __attribute__((visibility("hidden"))) func3(){
   printf("func3 in the shared library");
}
void __attribute__((visibility("internal"))) func4(){
   printf("func4 in the shared library");
}

//a.h
extern void func1();
extern void func2();
extern void func3();
extern void func4();

//b.c
#include "a.h"
void temp(){
   func1();
   func2();
}

//b.h
extern void temp();

//main.c
#include "a.h"
#include "b.h"

void func1(){
   printf("func1 in b.c");
}
void func2(){
   printf("func2 in b.c");
}
void main(){
   temp();
   // func3(); // error
   // func4(); // error
}
You can use the following commands to create a shared library named libtest.so:
xlc -c -qpic a.c b.c
xlc -G -o libtest.so a.o b.o
Then, you can dynamically link libtest.so during run time by using the following commands:
xlc main.c -L. -ltest -brtl -bexpall -o main
./main
The output of the example is:
func1 in b.c
func2 in the shared library
The visibility attribute of function func1() is default, so it is preempted by the function with the same name in main.c. The visibility attribute of function func2() is protected, so it cannot be preempted. The compiler always calls func2() that is defined in the shared library libtest.so. The visibility attribute of function func3() is hidden, so it is not exported in the shared library. The compiler issues a link error to indicate that the definition of func3() cannot be found. The same issue is with function func4() whose visibility attribute is internal.