I'm currently working on a massive overhaul of the visibility code to make it play nice with C++. One of the issues I've run into is the question of priority of #pragma visibility versus other sources of visibility information.

Consider:

  #pragma GCC visibility push(hidden)
  class __attribute((visibility("default"))) A
  {
    void f ();
  };

  void A::f() { }

Here I think we'd all agree that f should get default visibility.

  class A
  {
    void f ();
  };

  #pragma GCC visibility push(hidden)
  void A::f() { }
  #pragma GCC visibility pop

This case is less clear; A does not have a specified visibility, but the context of f's definition does. However, we don't want to encourage this kind of code; the visibility should be specified as early as possible so that callers use the right calling convention. Waiting until the definition to specify visibility is bad practice. Also, the status quo is that f gets A's visibility. I would preserve that and possibly give a warning to tell the user that they might want to add __attribute((visibility)) to the declaration of f in A.

Now, templates:

  template<class T> __attribute((visibility ("hidden")) T f(T);
  #pragma GCC visibility push(default)
  extern template int f(int);
  #pragma GCC visibility pop

This could really go either way. It could be considered similar to the above case in that f<int> is in a way "part" of f<T>, but there isn't the same scoping relationship. Also, there isn't the declaration/definition problem, as the extern template directive is the first declaration of the instantiation. In this case I am inclined to respect the #pragma rather than the attribute on the template.

Using an attribute would be less ambiguous:

  extern template __attribute ((visibility ("default")) int f(int);

In a PR Geoff asked if we really want to allow different visibility for different instantiations. I think we do; perhaps one instantiation is part of the interface of an exported class, but we want other instantiations to be generated locally in each shared object.

Jason

Reply via email to