Страницы

Поиск по вопросам

суббота, 4 января 2020 г.

Как размещаются стековые переменные в C

#c #gdb #x64


Здравствуйте. Я копаюсь с помощью отладчика в коде, и пытаюсь понять по какому принципу
GCC (C-compiler) размещает переменные (локальные) в стеке. Сначала я думал что он проталкивает
их в том же порядке:



то есть встретил int auth_flag и толкает в стек, переменная соответственно получает
больший адрес (т.к. стек растёт в направлении младших адресов). Потом password_buffer
уже получает адрес меньше. Но когда я поменял их местами -- ничего не изменилось:



auth_flag по прежнему получает адрес больше и (т.е. стоит ниже в стеке чем password_buffer).
Я бы подумал что так и должно быть, но этот пример взял с книги, и там, когда автор
меняет местами переменные, -- они меняются местами и в стеке. Книга за 2010 год, x32
архитектура, возможно GCC моложе. 

Поясните почему так происходит, почему компилятор не даёт самому выбирать порядок
размещения переменных и чем он "руководствуется" когда размещает переменные. 

GCC version: 4.9.2
    


Ответы

Ответ 1



Посмотрите на это с другой стороны. Если компилятор поменяет местами эти две переменные в стеке, это повлияет как-то на Ваш код? ответ - скорее всего Вы даже не узнаете об этом. А раз так, значит компилятор может расставить в стеке переменные так, как ему кажется правильным. И эти правила порой такие сложные, что только разработчики компилятора и процессора могут их аргументировать. Но есть случаи, когда компилятор может переставить ещё хитрее. Например, в так называемом RVO. Если в функции создается объект и он из нее возвращается, то компилятор может это увидеть и создать объект ещё в стеке вызывающей функции. Таким образом, экономится вызов конструктора копирования и деструктора. Но вернемся к вопросу, почему компилятор все-таки переставляет переменные? Он может ставить переменные так, что бы они были выровнены по границе в 16 байт - таким образом получится ускорение.

Комментариев нет:

Отправить комментарий