Почему-то все говорят о включении кода в выходной файл компилятором, хотя это вовсе не его задача. Задача компилятора - получить перемещаемый модуль, в который по умолчанию включаются ВСЕ глобально объявленные переменные. Включить переменные в выходной файл (отладочный, hex, bin) это уже работа линкера, т. к. обьявляться переменные могут в одном файле, а использоваться совсем в другом. И делает он это в том случае, когда к переменной было хоть одно обращение. Таким же способом включаются в выходной файл и программные модули. В противном случае вся мегабайтная библиотека была бы включена. Уровень оптимизации в этом случае не играет никакой роли! Дело только в востребованности того или иного обьекта (require).