Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Will a referenced library function be linked if it is not called?

Suppose we have the following iterface to a library:

// my_interface.h
typedef float (*myfunc)(float);
myfunc get_the_func();

And suppose that the implementation is as follows:

// my_impl.c
#include <math.h>
myfunc get_the_func() {
    return sinf;
}

And now suppose the client code does the following:

#include "my_interface.h"
...
myfunc func = get_the_func();
printf("%f\n", func(0.0f));

Does the standard guarantee that get_the_function() will return the address of the standard math library sinf()? If so, where in the standard is this implied? Please note the sinf() is not explicitly called anywhere.

like image 405
zr. Avatar asked May 13 '13 13:05

zr.


2 Answers

The standard does not require external functions to be called: being referenced is enough to be kept in the results of translation. According to the standard's section 5.1.1.2.1, during the eights (and last) phase of translation

All external object and function references are resolved. Library components are linked to satisfy external references to functions and objects not defined in the current translation.

Since returning a pointer to a function is considered a reference to it, the standard guarantees that sinf will be linked to whatever implementation that you supply to the linker, which may or may not be the one coming from the standard math library.

like image 147
Sergey Kalinichenko Avatar answered Nov 02 '22 23:11

Sergey Kalinichenko


The C standard doesn't guarantee that get_the_function() will return the address of the sinf function in the math library. The C standard guarantees that whatever the pointer is returned will be callable as if you called the sinf function and it will compare equal to any other pointer to that function.

On some architectures you might get a pointer to a descriptor of the function which the compiler handles specially and I've also seen function pointer values pointing to a dynamic linking trampoline and not the function itself.

I recall a discussion on the gcc mailing lists around 10 years ago if a function pointer cast to (void *) actually needs to compare equal to another function pointer cast to (void *) which was in connection with how IA64 implements function pointers (they could point to different descriptor structs in different libraries, which meant that to correctly implement compares the compiler would have to compare the contents of the descriptors and not the pointers themselves). But I don't remember what the standards lawyers decided and/or if this was solved in the linker.

like image 22
Art Avatar answered Nov 03 '22 00:11

Art