Answered By dps on Thu, 08 Jun 2000
There are valid reasons other than those evil one you give for wanting to limit the exported symbols---prime examples are big jobs split into multiple source files, which export symbols that implement the feature. Normally one would not want to export these symbols after linking the library.
IF anyone wants to use undocumented functions that for advanatge over the competition then removing it also stops them linking those functions. A little reading of the binutils man page will reveal, for example the -L optionm in objcopy
-L symbolname, --localize-symbol=symbolname Make symbol symbolname local to the file, so that it is not visible externally. This option may be given more than once.
which seems to fit the bill. (Several symbols in the resolver code became local in the glibc 2.0 yto glibc 2.1, breaking various programs that used the undocumented behaviour of those symbols.)
The main differences is that M$ dll's seem to require you to explicitly list what is externally visible, unlike most unicies and their shared libraries.
I didn't think I characterized it as "evil." I just didn't think it would be very useful.I didn't think I characterized it as "evil." I just didn't think it would be very useful.
However, you've shown me a new trick. I hope my earlier correspondent checks back if he or she still needs this tidbit.
Answered By Steven G. Johnson on Tue, 30 May 2000
Hi, noticed your answer regarding "public interfaces" in shared libraries in the latest Linux Gazette, and I had a couple of comments. (I am a programmer, and have written several libraries and shared libraries under Linux.)
There are at least two good reasons to hide functions from public interfaces:
- If a function is internal to the library, and it may well disappear or change incompatibly without warning in future versions, so that you don't want to be worry about people using it.
Any library will almost certainly contain a large number of such internal functions, and the code would be utterly unmaintainable if you couldn't change them between releases because people depended on them.
Of course, it is usually sufficient to simply not document those functions or declare them in your header files, so that programmers who find out about them should know that they use them at their own risk. (Some programmers are foolish enough to do so, even though it is almost never a good idea. e.g. there was a well-known case where StarOffice had depended upon internal glibc functions and therefore broke when glibc was upgraded.)
- If you don't want to pollute the namespace.
If I have an internal function in my library called something generic, like print_error, I run the risk of accidentally conflicting with a function of the same name in a calling program, with unpredictable results. One way around this is to prefix the function with the name of my library, calling it e.g. foo_print_error if my library is libfoo. But this can be awkward to do for every little internal function you write, and it is often preferable to simply hide them from the linker.
There is a solution, however, provided by ANSI C: simply declare your functions with the "static" keyword, and they will only be visible/callable within the file they are defined in. This isn't perfect, I suppose, because they also aren't visible to other files in the same library. However, it covers the case where foo_ prefixes are most annoying: little utility functions that are only called within one file.
Cordially,
Steven G. Johnson