@evgeniy2003

Где хранится имя переменной?

И снова здравствуйте всем лютым программерам на хабре, как всегда прошу не кидаться тухлыми помидорами, ибо только начинаю изучать тему. В общем решил поюзать unity, долго к этому шел, но не суть. Это мой второй вопрос по unity, в книге написано, постараюсь сформулировать максимально точно, искать лень, в общем там написано типа значение примитивов переменных хранится в стеке, а таких как string в куче. Все вроде логично и понятно, но где хранится само имя переменной нигде не написано:(
  • Вопрос задан
  • 239 просмотров
Решения вопроса 4
freeExec
@freeExec
Участник OpenStreetMap
1А) нигде
1Б) в метаданных
Смотря для чего тебе это "имя"
Ответ написан
@Akela_wolf
Extreme Programmer
От сложного к простому:
1. Программирование в машинных кодах. "Что такое имя переменной?". А нету его, как вы правильно заметили. На уровне машинного кода есть только циферки. Переменные могут храниться в регистрах процессора или в оперативной памяти по какому-то адресу. И программист должен везде указывать код регистра или адрес памяти к которому обращается программа. Впрочем, программирование в машинных кодах осталось далеко в прошлом (с появлением языков ассемблера, это конец 40-х).
2. Язык ассемблера. Тут можно задать псевдонимы для адресов памяти. Но это именно псевдонимы. Так как на ассемблере программист полностью контролирует память программы - он сам решает какой блок памяти как называть. В процессе сборки ассемблер заменит псевдонимы на реальные адреса памяти.
3. Языки высокого уровня (такие как C/C++, Паскаль, FORTRAN, LISP и т.п.). Компилятор сам планирует использование памяти и назначает переменным какие-то адреса (может разместить переменную в регистре, может в стеке, может даже в динамической памяти). На этапе компиляции в машинный код помещаются только адреса переменных.

Собственно на этих исторических этапах имя переменной нигде не хранится. И по коду программы можно понять что в каком-то адресе памяти размещена некая переменная, но узнать её имя (каким оно было в исходном коде) нельзя никаким образом. Впрочем, есть одно исключение - таблица отладочных символов. Это именно то соответствие "имя-адрес", чтобы программисту было проще отлаживать программу. Используя эту таблицу отладчик может "подписать" адреса в памяти, облегчая программисту понимание что происходит внутри программы. Но это касается именно отладки, для работы программы эта таблица не нужна и конечному пользователю, как правило, не предоставляется.

4. Байт-код. Это касается языков с виртуальными машинами, таких как Java, C# и подобных. Компилятор преобразует текст программы в промежуточный байт-код. И в этом байт-коде могут сохраняться имена переменных (в частности в Java сохраняются имена классов, полей классов, методов классов). Могут - потому что могут и не сохраняться, допустим не сохраняются имена аргументов функций и локальных переменных (в Java, про C# утверждать не буду), в байт-коде на них ссылаются по порядковому номеру. Нужны они в байт-коде для работы механизма рефлексии, то есть когда программа обращается "сама к себе", спрашивая: "Какие свойства есть у этого объекта?" (имеет смысл, например, если объект из какого-нибудь плагина, то есть код на момент своей компиляции об этом объекте и понятия не имел). Но когда виртуальная машина исполняет байт-код, то она преобразует его в машинный код в котором, опять же, каждой переменной сопоставлен какой-то регистр процессора или адрес памяти.

Таким образом, если мы говорим о компилируемых в машинный код языках ответом будет "нигде" или "в таблице отладочных символов". Если мы говорим о компилируемых в байт-код языках, то ответом будет "в байт-коде (в метаданных), но это не точно"
Ответ написан
Комментировать
firedragon
@firedragon
Не джун-мидл-сеньор, а трус-балбес-бывалый.
в метаданных или нигде. Второе требует объяснения, компилятор разбирая исходный код создает таблицу переходов и при вызове функции просто перекидает на нужный адрес.
Собственно поэтому так медленно все и компилируется.
Есть еще рефлексия, крайне тормознутая, но очень мощная штука.
Ответ написан
vabka
@vabka Куратор тега C#
Токсичный шарпист
1. Переменных после компиляции нет - это просто значения на стеке, с которыми производятся какие-то операции (даже адресов на таком уровне абстракции нет)
2. На счёт vtable не подскажу, но там вроде уже есть имена методов и указатели на реализацию.
3. Переменная ссылочного типа (например string) - это ссылка на стеке, которая указывает на данные в куче.
4. Имён локальных переменных даже в метаданных нет

После компиляции в машинный код - процессор работает с последовательностями байтов, числами, указателями. Тоже никаких переменных нет

Советую обратить внимание на сайт sharplab.io - там ты можешь увидеть, как выглядит твой код на разных этапах, начиная с парсинга в AST, заканчивая ассемблером
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы