# C++ AVR big code size & excess unused symbols in build file

I'm developing the program for the AVR microcontroller in C++. I have created a class that contains 8 methods(with constructors) but used only 3. Class code:

class Pin {
Pin();
Pin(PinId pin_id);
Pin(Port port, uint8_t pin);

void SetDirection(Direction direction);
Direction GetDirection() const;

void Write(Signal signal);

void Toggle();
};


I expect that in the build file unused methods won't be, but it will. I use the Ghidra disassembler to disassemble the build file. Pin(Port port, uint8_t pin), SetDirection and Toggle are used only (simple LED flasher). But there are all of these methods in the build file and there are no references to these methods. So, why compiler/optimizer/linker doesn't remove these methods from the build file? I compile the program with -Os optimization parameter and Release CMake configuration. For example, the Write method in the Ghidra: But the Write method isn't used in my code (and in other class' methods too). How can I optimize it? Thanks in advance!

• what file exactly did you analyze? usually, at the end of everything, you might be getting e.g. an ELF file that still contains symbol names, but these would be discarded upon loading the ELF using a debugger into the device's RAM, or during a step that gives you the plain binary. Of course, if you use C++ and Reflection, or extensive virtual inheritance, you can't throw away any symbols early. – Marcus Müller Jan 2 at 14:04
• @MarcusMüller, I analyzed the ELF file compiled by avr-g++. I don't use virtual functions. Output of avr-size is Program: 682 bytes and Data: 0 bytes – manueld4722623 Jan 2 at 14:11
• @MarcusMüller, I just removed a few unused methods from the class and the output from avr-size decreased from 682 bytes to 548. – manueld4722623 Jan 2 at 14:13
• to see in more detail the size of functions etc, have it output a .map file – Pete W Jan 2 at 14:29
• @PeteW, yeah, it worked, code size reduced to 472 bytes, thanks. You can post the answer if you want – manueld4722623 Jan 2 at 14:56

If using GCC (AVR-GCC), the following options can be helpful

Compiler:

-fdata-sections -ffunction-sections

-Wl,--gc-sections

The above options work together as follows

-ffunction-sections and -fdata-sections -- these put each function or data item into its own section in the output file (i.e. object file coming out of compiler). At this stage it's too soon to say whether we can garbage collect anything, only when linking will there be enough information to make that decision, hence the linker option below

-Wl,--gc-sections -- figures out if there are "sections" that are never used and removes them ("garbage-collection")...

Reference: the documentation

Also, examining the .map file is a way to deduce how much individual functions/methods or static data items are contributing to the total size

• Upvoted, but a short explanation what those compiler options actually do, would be nice to complete this answer. – Grebu Jan 4 at 12:25
• @Grebu - updated – Pete W Jan 4 at 15:20