0

My feeling is that essentially 100% of the time this is what you would want to happen, but I suspect that there might be some theoretical caveats, for example:

Say I statically link the standard library and I use printf but not sprintf. Further suppose that I know that &sprintf == &printf + SPRINTF_OFFSET. How could the compiler know I'm never accessing sprintf like this? Does the standard prohibit it somehow?

too honest for this site
  • 12,050
  • 4
  • 30
  • 52
Benjamin Lindqvist
  • 4,300
  • 3
  • 18
  • 19
  • 1
    You can't do computations on function addresses as shown (you'd need casts to `uintptr_t` or similar, and then cast back to a suitable function pointer, at minimum — and `sprintf()` won't be at a fixed offset). The linker links object files from the static library that satisfy unsatisfied references in the previous object code. It won't pull in other uncalled functions unless they're part of the same object file as the one that is called. It iterates until there are no more references that can be satisfied by the static library; then it moves onto the next library in the linker command line. – Jonathan Leffler Aug 05 '18 at 17:25
  • 2
    How could you know the offset, if one of the two functions is not linked? – Yunnosch Aug 05 '18 at 17:26
  • @Yunnosch good point. – Benjamin Lindqvist Aug 05 '18 at 17:27
  • Is there a version of your question (which I find somewhat interesting but cannot give a substantial "not possible" answer to), without that logical obstacle? Try to rephrase around it, otherwise I fear the question might be closed as "cannot be reproduced". – Yunnosch Aug 05 '18 at 17:31
  • On the other hand, if you consider my nitpicking to be a negative but otherwise helpful answer, let me know, then I will of course turn my comment into an official answer. – Yunnosch Aug 05 '18 at 17:34
  • I think it was very helpful. I can only imagine one possible counter: We have a program that parses its own binary representation looking for something that looks like `sprintf`, then casts it to a function pointer and calls it. It seems to me that in this case the standard needs to explicitly dictate how unreferenced functions should be linked, otherwise we have UB. Right? – Benjamin Lindqvist Aug 05 '18 at 17:40
  • I am not trying to insult anybody, I also work in an environment where something as "creative" as that is imaginable. But it is **so** creative that I do not expect a generally applicable answer (which I think your question wants). In my opinion that method is very far off anything remotly reliable. I have no idea how to look for something which "looks like sprintf". Could you not add a little call to sprintf() to ensure it is linked? I guess you are looking at extreme memory optimisation needs (which I am also used to), but ensuring reliability is usually high prio in that kind of scope, too. – Yunnosch Aug 05 '18 at 18:05
  • Lets turn the reasoning around. If you can afford the code for scanning for something "looking like sprintf", then you can afford the code to ensure it is linked and have a reliable address. The scanner code becomes unneeded in that case. – Yunnosch Aug 05 '18 at 18:08
  • In order to minimise guessing, join me in a chat please: https://chat.stackoverflow.com/rooms/177450/room-for-yunnosch-and-benjamin-lindqvist – Yunnosch Aug 05 '18 at 18:11

1 Answers1

-1

If I statically link a C library, will the unused functions be optimized out?

Yes, provided they are not part of an object that is pulled into the link via some other symbol.

To understand how the linker works, read this or this.

How could the compiler know I'm never accessing sprintf like this?

The C language standard prohibits computing a pointer that doesn't point to a valid object, or just beyond the last element of an array. Your example is ill-formed.

Employed Russian
  • 199,314
  • 34
  • 295
  • 362
  • I'd accept this if you posted a link explaining your second paragraph. The term "invalid object" seems very imprecise to me. – Benjamin Lindqvist Aug 06 '18 at 05:06
  • @BenjaminLindqvist There is no "invalid object" in my answer. If you want the precise chapter and verse, start with "6.2.4 Storage durations of objects" of the C standard, which defines how objects become valid (start their lifetime) and how the object lifetime ends (at which point the object is no longer valid). – Employed Russian Aug 06 '18 at 05:16
  • Yes there is, you wrote that the standard prohibits computing a pointer that doesn't point to a "valid object". Besides, I fail to see how "storage duration" applies to a statically linked function. Please quote the relevant parts of the standard. – Benjamin Lindqvist Aug 06 '18 at 17:05
  • Prob better to not bother because the original question is slightly too low quality anyway. – Benjamin Lindqvist Aug 06 '18 at 17:12