The compiler supports nested visibility pragma preprocessor directives. If entities are included in several pairs of the nested #pragma GCC visibility push and #pragma GCC visibility pop directives, the nearest pair of directives takes effect. See Example 1.
You must not specify the visibility pragma directives for header files. Otherwise, your program might exhibit undefined behaviors. See Example 2.
Visibility pragma directives #pragma GCC visibility push and #pragma GCC visibility pop affect only namespace-scope declarations. Class members and template specializations are not affected. See Example 3 and Example 4.
Example 1
In this example, the function and variables have the visibility attributes that are specified by their nearest pairs of pragma preprocessor directives.#pragma GCC visibility push(default)
namespace ns
{
void vis_f_fun() {} //default
# pragma GCC visibility push(internal)
int vis_v_i; //internal
# pragma GCC visibility push(protected)
int vis_v_j; //protected
# pragma GCC visibility push(hidden)
int vis_v_k; //hidden
# pragma GCC visibility pop
# pragma GCC visibility pop
# pragma GCC visibility pop
}
#pragma GCC visibility pop
Example 2
In this example, the compiler issues a link error message to indicate that the definition of the printf() library function cannot be found.#pragma GCC visibility push(hidden)
#include <stdio.h>
#pragma GCC visibility pop
int main(){
printf("hello world!");
return 0;
}
Example 3
In this example, the visibility attribute of class members vis_v_i and vis_f_fun() is hidden. The visibility attribute is propagated from that of the class, but is not affected by the pragma directives.class __attribute__((visibility("hidden"))) A{
#pragma GCC visibility push(protected)
public:
static int vis_v_i;
void vis_f_fun() {}
#pragma GCC visibility pop
} vis_v_a;
Example 4
In this example, the visibility attribute of function vis_f_fun() is hidden. The visibility attribute is propagated from that of the template specialization or partial specialization, but is not affected by the pragma directives.namespace ns{
#pragma GCC visibility push(hidden)
template <typename T, typename U> class TA{
public:
void vis_f_fun(){}
};
#pragma GCC visibility pop
#pragma GCC visibility push(protected)
//The visibility attribute of the template specialization is hidden.
template <> class TA<char, char>{
public:
void vis_f_fun(){}
};
#pragma GCC visibility pop
#pragma GCC visibility push(default)
//The visibility attribute of the template partial specialization is hidden.
template <typename T> class TA<T, long>{
public:
void vis_f_fun(){}
};
#pragma GCC visibility pop