Может ли компилятор C переставлять переменные стека?
В прошлом я работал над проектами для встраиваемых систем, где мы изменили порядок объявления переменных стека, чтобы уменьшить размер получаемого исполняемого файла. Например, если бы мы имели:
void func()
{
char c;
int i;
short s;
...
}
Мы бы переупорядочили это так:
void func()
{
int i;
short s;
char c;
...
}
Из-за проблем с выравниванием первый приводил к использованию 12 байт стекового пространства, а второй - только 8 байт.
Это стандартное поведение для компиляторов C или просто недостаток компилятора, который мы использовали?
Мне кажется, что компилятор должен иметь возможность переупорядочивать переменные стека в пользу меньшего размера исполняемого файла, если он этого хочет. Мне было предложено, что некоторый аспект стандарта C предотвращает это, но я так и не смог найти авторитетный источник.
В качестве дополнительного вопроса, это также относится к компиляторам C ++?
редактировать
Если ответ «да», компиляторы C / C ++ могут переставлять переменные стека, можете ли вы привести пример компилятора, который определенно делает это? Я хотел бы видеть документацию компилятора или что-то подобное, что подтверждает это.
Редактировать снова
Спасибо всем за вашу помощь. Что касается документации, лучшее, что я смог найти, это бумагаОптимальное назначение слотов стека в GCC(pdf), Навин Шарма и Санджив Кумар Гупта, который был представлен на саммите GCC в 2003 году.
Рассматриваемый проект использовал компилятор ADS для разработки ARM. В документации для этого компилятора упоминается, что объявления порядка, как я показал, могут улучшить производительность, а также размер стека, из-за того, что архитектура ARM-Thumb вычисляет адреса в фрейме локального стека. Этот компилятор не переставил локальные переменные, чтобы воспользоваться этим. В этом документе говорится, что с 2003 года GCC также не переставлял фрейм стека, чтобы улучшить местность ссылок для процессоров ARM-Thumb, но это подразумевает, что вы могли бы.
Я не могу найти ничего, что определенно говорит, что это когда-либо было реализовано в GCC, но я думаю, что этот документ считается доказательством того, что вы все правы. Еще раз спасибо.