It indeed makes things easier, if your program will be moving around in its own addressing space (or in another processes addressing space) and not just standing at the entry point specified in its ELF header (for GNU/Linux systems), then it is very handy to do not depend on anything external.
To better understand why, we need to roughly known a libc C function is invoked:
- Call an entry on a memory table (
PLT
Procedure Linkage table) - At the first invocation, the dynamic linker is fired to resolve the address of the function you want to call in the library (and even load the library if needed)
- Then, the entry in that memory table is patched with the resolved address so, next time, it does not need to call the dynamic linker (you already know where the function is located).
So, even in the stationary case (whenever all the symbols your program uses have been resolved), all your calls to a libc function goes through an indirection. For the gory details check theses two great post at 0x00sec
So, coming back to your question. Once the PLT table is resolved/updated, you can just call any libc function from any memory position, through that table. In order to make your program Position Independent you need to let the compiler know, independently of the libraries you use. So, I do not see a big advantage on that side.
However, if you want your code to be loaded using non standard techniques (as it may happen with a virus or other malwares), having all your program self-contained makes things easier as you do not have to care about linking or resolving symbols… on the other hand, whatever functionality you need, you will have to implement your self/add to your program manually… Which, depending on what the program has to do may be quite some work…