0

-- as described at the GCC Wiki - Visibility. I have exercised How to use the attribute((visibility("default")))? and Simple C++ Symbol Visibility Demo but still do not understand some parts of the GCC Wiki - Visibility article.

At its Step-by-step_guide you find

For every non-templated non-static function definition in your library (both headers and source files), decide if it is publicly used or internally used

In the other examples I found that it is sufficient to only decorate the declarations in the header files. Why also decorate the definitions in the source files?

If it is publicly used, mark with FOX_API like this: extern FOX_API PublicFunc()

I haven't seen this extern keyword in the other examples and I have never used it for public functions. Why do I have to use it here?

The given macro starts with

#ifdef FOX_DLL // defined if FOX is compiled as a DLL

If using CMake where or how is FOX_DLL defined?

Ingo
  • 588
  • 9
  • 21
  • The question about `FOX_DLL` is Cmake-related, I suggest to move it to dedicated question. – yugr Nov 11 '21 at 10:32

2 Answers2

1

In the other examples I found that it is sufficient to only decorate the declarations in the header files. Why also decorate the definitions in the source files?

If global function is declared in a header and that header is included in source file where function is defined, annotation in header will suffice (compiler will indeed pick up the attribute from the header). Otherwise you'll need to annotate it in source code.

I haven't seen this extern keyword in the other examples and I have never used it for public functions. Why do I have to use it here?

The extern keyword is optional in function declarations but it's often used for clarity.

yugr
  • 19,769
  • 3
  • 51
  • 96
  • "*annotation in header will suffice ... Otherwise you'll need to annotate it in source code.*" - How would I call the global function in another source file without header file? For me the note in the [GCC Wiki - Visibility](https://gcc.gnu.org/wiki/Visibility) does not make much sense (except by including the source file). – Ingo Nov 16 '21 at 11:00
  • 1
    @Ingo "How would I call the global function in another source file without header file" - by manually declaring `extern void foo()` in source file. Note that header is just that, a bunch of `extern` declarations which are inserted into source file by preprocessor. – yugr Nov 16 '21 at 17:05
  • Ah.. yes, of course. Doesn't thought of this. – Ingo Nov 16 '21 at 18:27
0

You might be confused by two opposite approaches to visibility. You name both GCC (which comes from the UNIX corner) and DLL (which comes from the Windows corner).

UNIX by default has full visibility, Windows by default has no visibility. As a result, to modify these two defaults, you have to move in opposite directions.

C++ (and C prior to it) did not have the notion of shared libraries or visibility, which makes sense: there wasn't much to standardize. You end up with non-portable approaches like this.

MSalters
  • 173,980
  • 10
  • 155
  • 350
  • 1
    "to modify these two defaults, you have to move in opposite directions" - just wanted to point out that the _recommended_ approach on Linux is to use `-fvisibility=hidden` to hide all symbols by default and then selectively export public ones via `__attribute__((visibility("default")))`. This makes it identical to Windows. – yugr Nov 16 '21 at 17:18