Может ли компилятор 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, но я думаю, что этот документ считается доказательством того, что вы все правы. Еще раз спасибо.

Ответы на вопрос(11)

Ваш ответ на вопрос