Search code examples
c++gccdlldllimportdllexport

Why does MSVC (Visual C++) need separate dllimport and dllexport attributes and gcc not?


I know why and when __declspec(dllimport) and __declspec(dllexport) are used in Visual C++.

I know the GCC alternative to both __declspec(dllimport) and __declspec(dllexport) is __attribute__((visibility("default"))).

I'm just wondering why Visual C++ does need both commands, while GCC is able to figure out itself whether it should import or export the symbol?

Are there some disadvantages of the GCC approach, f.ex. by exporting (templated/inlined) functions that should have been imported instead?

Of course the easy answer is: "It's a design choice of GNU/Microsoft", maybe it's the only answer. Thank you for your input!


Solution

  • I don't have the knowledge to elaborate on the internals of gcc but you can experiment yourself noticing that both gcc/llvm, when compiling with -fvisibility=hidden, will export symbols in the shared library text section (T type symbol in nm -gD command output) only for the ones where the visibility("default") is restored and the method/type is properly defined within the library boundary. Users of such library (such as other shared libraries) will not re-export those in the text section, even if they are decorated with default visibility, but will just manifest their use as undefined symbols (U type symbols in nm output). gcc/llvm clearly has the information at linking time to determine which table the symbol must be written in, distinguishing between (using the MSVC terminology) export and import usage. It's also important to observe that some features, such as RTTI, may not work properly if symbols are accessed with inconsistent linkage, so it's better that the default visibility attribute is always present in the library headers.