0

How do I prevent namespace collisions in a library? Let's say I have a internal library function called foo(), that is not included in a public header, so the user doesn't know about this function. But foo() is used across multiple files and can't be declared static.

The Problem is, if the user now creates a function called foo(), there is an error. How do I prevent namespace collision (as the library author), without forcing the user to not use specific function names? example.c

#include <stdio.h>

void foo() {
    printf("my foo called");
}

int main() {
    foo();
}

lib.c

#include <stdio.h>

void foo() {
    printf("library foo() called\n");
}

output:

$ gcc -Wall -Wextra -Werror example.c example-lib.c
/usr/bin/ld: /tmp/cci3Dd3J.o: in function `foo':
example-lib.c:(.text+0x0): multiple definition of `foo'; /tmp/ccneOJjI.o:example.c:(.text+0x0): first defined here
collect2: error: ld returned 1 exit status

Edit

I now tried the following (with the same files):

$ gcc -Wall -Wextra -Werror example-lib.c -fpic -shared -o example-lib.so
$ gcc -Wall -Wextra -Werror example.c example-lib.so

And for some reason it works. Can anyone explain why?

Tenobaal
  • 637
  • 1
  • 16
  • Your compile command does not link with a properly built library, but is simply compiling/linking multiple objects. A properly built library can export symbols selectively. – Eugene Sh. Nov 04 '22 at 15:55
  • Does this answer your question? [How do you prevent names from colliding in C](https://stackoverflow.com/questions/15125059/how-do-you-prevent-names-from-colliding-in-c) – Binary Worrier Nov 04 '22 at 15:55
  • *Let's say I have a internal library function called foo(), that is not included in a public header, so the user doesn't know about this function.* - so the user knows once trying to compile it... – Eugene Sh. Nov 04 '22 at 15:57
  • I have done it like this `PV__fn` where PV stands for `private`. – Marco Nov 04 '22 at 15:59
  • I would definitely include the library name, to be more confident that it will not collide with a user function. – Marco Nov 04 '22 at 16:00
  • so I have to call every function, for example *libname*_foo()? – Tenobaal Nov 04 '22 at 16:01
  • 1
    @Tenobaal Yes, I think that's a clean way to do it. Well, `libname_foo` for public functions and `PV_libname_foo` for private ones.. – Marco Nov 04 '22 at 16:01
  • I don't like libraries that pollute the global namespace without any prefix. – Marco Nov 04 '22 at 16:02
  • @EugeneSh. What do you mean by `A properly built library can export symbols selectively.` are you saying it's possible to have names like `foo()` in a library without using static AND without exporting it to the end-user? – Marco Nov 04 '22 at 16:04
  • @EugeneSh. If you could tell me how, my question would be solved. – Tenobaal Nov 04 '22 at 16:06
  • Regarding your edit @Tenobaal `gcc -Wall -Wextra -Werror example.c example-lib.so` is wrong, that's not how you use a shared library. This is how you would use a statically linked library (`.a`) . – Marco Nov 04 '22 at 16:06
  • 2
    @marco-a Well, perhaps not universally: https://www.gnu.org/software/gnulib/manual/html_node/Exported-Symbols-of-Shared-Libraries.html – Eugene Sh. Nov 04 '22 at 16:06
  • @marco-a And how do I do it correctly? – Tenobaal Nov 04 '22 at 16:07
  • A shared library is loaded at runtime (`dlopen`, `dlsym`). A statically linked library's code is embedded in the program. – Marco Nov 04 '22 at 16:07
  • `A shared library is loaded at runtime` that's the whole point of shared libraries, so multiple programs can use _the same_ library. – Marco Nov 04 '22 at 16:09
  • 1
    @marco-a You don't have to use `libdl` to use shared libraries. Shared libraries are the normal way to link these days, and they'll be loaded automatically. You only need to use `libdl` if you're loading libraries dynamically. – Barmar Nov 04 '22 at 16:10
  • @Barmar I see. I haven't used shared libraries so far, so I haven't really the experience working with them. I guess `gcc -Wall -Wextra -Werror example.c example-lib.so` is correct then? – Marco Nov 04 '22 at 16:13
  • @EugeneSh. Thanks this is exactly what I was hoping to find. – Tenobaal Nov 04 '22 at 16:14
  • I would say a properly designed library would be equally buildable and usable as either a static linked library or a dynamic-linked library, so yes a well designed library would use internally shared non-public functions by giving them names with a prefix or suffix that the library's documentation would declare to be private and for internal use only. For added bonus the library's public header could define those names to macros that would cause a compilation error (i.e. a static assertion) if they were accidentally used in the caller's code. – Greg A. Woods Nov 06 '22 at 21:39

0 Answers0