On many modern systems, at link time it will determine the address of the function relative to the base address module. When the module (exe, dll, or so) is loaded, Address Space Layout Randomization (ASLR) gives it a different base address.
This is for security, it means the addresses of functions is not predictable. This means certain attacks that might for example overflow a stack variable to overwrite the return address or a function pointer with some other function (for malicious purposes), can't easily predict what address to overwrite it with, it will vary from run to run.
The ability to relocate the base address also solves the practical problem of a conflict, if you load a.dll and b.dll which were independently compiled for the same base address, that won't work, so being able to relocate one resolves the conflict.
At the machine code level, this is fine because most jumps and calls use a relative instruction offset, not an absolute. Although certain constructs are dynamically patched when the module is loaded, or use some form of "table" that is populated with the correct addresses.
See also Relocation (computing)