> Does nm(1) show you that unused functions are absent?
yes, of course. We're not just making this up, you know.Arduino in particular is heavily reliant on this linker/compiler feature get get rid of most of the class methods that C++ programmers love to add to their source code, which are hardly ever all used in the same sketch.
For an obvious example, compile a simple "Serial.print("Hello World");" sketch and note that the .elf file ends up with only:
WWHackintosh<10025> avr-nm -SC sketch_jul20a.ino.elf | grep Print
00000114 00000006 t Print::availableForWrite()
00000112 00000002 t Print::flush()
000000be 00000054 t Print::write(unsigned char const*, unsigned int)In spite of Print.cpp.o being much more ... bloated:
WWHackintosh<10026> avr-nm -SC ../arduino_build_474806/core/Print.cpp.o | grep print
00000000 000001b6 T Print::printFloat(double, unsigned char)
00000000 00000092 T Print::printNumber(unsigned long, unsigned char)
00000000 00000048 T Print::print(__FlashStringHelper const*)
00000000 00000004 T Print::print(char const*)
00000000 0000001c T Print::print(String const&)
00000000 00000014 T Print::print(Printable const&)
00000000 0000000e T Print::print(char)
00000000 00000004 T Print::print(double, int)
00000000 0000000e T Print::print(unsigned char, int)
00000000 0000000e T Print::print(int, int)
00000000 0000000c T Print::print(unsigned int, int)
00000000 00000090 T Print::print(long, int)
00000000 0000001a T Print::print(unsigned long, int)
00000000 00000024 T Print::println(__FlashStringHelper const*)
00000000 00000024 T Print::println(char const*)
00000000 00000024 T Print::println(String const&)
00000000 00000024 T Print::println(Printable const&)
00000000 00000024 T Print::println(char)
00000000 00000024 T Print::println(double, int)
00000000 00000024 T Print::println(unsigned char, int)
00000000 00000024 T Print::println(int, int)
00000000 00000024 T Print::println(unsigned int, int)
00000000 00000024 T Print::println(long, int)
00000000 00000024 T Print::println(unsigned long, int)
00000000 00000008 T Print::println() >What actually happens when you pass those flags may be target dependent.
No, it's pretty platform-independent. And sort of obvious in retrospect - it just tells the compiler to generate object files in a way that makes it possible for the linker to treat individual functions as if they had come from individual .o files. Whether existing libraries are compiled with the necessary compiler switches is another question. AFAIK, while it's "obviously easy" for a compiler to put each function in a separate "section" (-ffunction-sections) during the compile phase, it's not possible to split up an existing .o file...
Although my impression is that outside of the embedded arena, most programs simply map in huge .dll run-time libraries with no attempt to optimize which functions are actually present. "If it's not used, the pager will never read it in. Maybe. Who cares - 8GB of RAM and 64bits worth of address space!"