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