Specifying visibility attributes using pragma preprocessor directives (IBM extension)

You can selectively set visibility attributes for entities by using pairs of the #pragma GCC visibility push and #pragma GCC visibility pop preprocessor directives throughout your source program.

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.

C++ onlyVisibility 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.C++ only

Examples

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;
}  
C++ only

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
C++ only